Android片段和动画

问题描述 投票:255回答:6

你应该如何实现那种例如Honeycomb Gmail客户端使用的滑动?

TransactionManager可以通过添加和删除片段自动处理这个,由于模拟器是幻灯片,所以很难测试这个:)

android android-fragments android-3.0-honeycomb
6个回答
376
投票

要设置片段之间的过渡动​​画,或者为显示或隐藏片段的过程设置动画,请使用Fragment Manager创建Fragment Transaction

在每个片段事务处理中,您可以指定分别用于显示和隐藏的输入和输出动画(或者在使用替换时两者都指定)。

下面的代码显示了如何通过滑出一个片段并将另一个片段滑动到其中来替换片段。

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

为了实现隐藏或显示片段的相同功能,您只需调用ft.showft.hide,传入要分别显示或隐藏的片段。

作为参考,XML动画定义将使用objectAnimator标记。 slide_in_left的示例可能如下所示:

<?xml version="1.0" encoding="utf-8"?>
<set>
  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x" 
    android:valueType="floatType"
    android:valueFrom="-1280"
    android:valueTo="0" 
    android:duration="500"/>
</set>

233
投票

如果您不必使用支持库,那么请查看Roman's答案。

但是如果你想使用支持库,你必须使用旧的动画框架,如下所述。

在咨询Reto'sblindstuff's答案后,我得到了以下代码。

碎片从右侧滑入,按下后部向左滑动。

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

订单很重要。这意味着您必须在setCustomAnimations()之前调用replace()或动画不会生效!

接下来,这些文件必须放在res / anim文件夹中。

enter.xml:

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

exit.xml:

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="-100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml:

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="-100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml:

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

动画的持续时间可以更改为任何默认值,如@android:integer/config_shortAnimTime或任何其他数字。

请注意,如果在片段替换之间发生配置更改(例如旋转),则不会对后退操作进行动画处理。这是documented bug,仍然存在于支持库的rev 20中。


18
投票

我强烈建议你使用它而不是创建动画文件,因为它是一个更好的解决方案。 Android Studio已经提供了您可以使用的默认animation,而无需创建任何新的XML文件。动画的名称是android.R.anim.slide_in_left和android.R.anim.slide_out_right,您可以按如下方式使用它们:

fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left,android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();              
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

输出:

enter image description here


5
投票

我修改过的support library支持使用View动画(即<translate>, <rotate>)和Object Animators(即<objectAnimator>)进行片段转换。它是用NineOldAndroids实现的。有关详细信息,请参阅github上的文档。


1
投票

我解决这个方式下面

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment

1
投票

至于我,我需要查看方向:

在 - >从右边滑动

out - >向左滑动

这适用于我的代码:

slide_in_right.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_left.xml

 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
    </set>

交易代码:

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.