如何在 BackStack 上反转片段动画?

Posted

技术标签:

【中文标题】如何在 BackStack 上反转片段动画?【英文标题】:How to Reverse Fragment Animations on BackStack? 【发布时间】:2012-06-08 20:13:40 【问题描述】:

我认为在使用以下代码使用片段时按下后退按钮时系统会在后台堆栈上反转动画:

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out);
ft.replace(R.id.viewContainer, new class(), "layout").addToBackStack(null).commit();

【问题讨论】:

【参考方案1】:

根据android documentation for custom animation:

变化:

ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out);

收件人:

ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out, R.anim.hyperspace_in, R.anim.slide_out );

现在 backstack 动画了 - 反过来!!

【讨论】:

顺便说一句,我知道这与您的问题和答案无关,但是您能否将我链接到一些解释 customAnimations 的内容? :P AreusAstarte:见developer.android.com/reference/android/app/…, int, int, int) 嗨,我实际上正在使用内容转换,工作正常,但是当我按下并转到上一个片段时,背景只是消失了动画视图,但也覆盖了以前的视图,有什么办法可以避免这种情况? 【参考方案2】:

使用正确的动画 我已经使用了以下内容,它的工作原理就像一个魅力

slide_in_left.xml

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

slide_in_right.xml

 <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime" >

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="1000"
        android:valueType="floatType" />

</set>

slide_out_left.xml

   <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime" >

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="-1000"
        android:valueType="floatType" />

</set>

slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime" >

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:propertyName="x"
        android:valueFrom="-1000"
        android:valueTo="0"
        android:valueType="floatType" />

</set>

然后在添加片段时使用以下内容

setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left,
                                R.anim.slide_out_right, R.anim.slide_in_right)

它会 100% 工作

【讨论】:

请注意,如果您正在使用支持片段管理器或如果您的片段扩展了片段的支持版本,这将不起作用 @w3bshark 如何使用支持库中的FragmentManagerFragment 使此类动画正常工作? @DanielShatz 您必须使用翻译而不是 objectAnimators。例如,slide_in_left.xml 将是:&lt;translate android:fromXDelta="100%" android:startOffset="25" android:toXDelta="0" /&gt; 请参阅此答案:***.com/a/5151774/1738090 我正在尝试这个(在 Marshmallow 设备上 - 没有尝试其他版本)。它不起作用。 final FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); fragmentTransaction.replace(R.id.fl_right_container, detailFragment); fragmentTransaction.replace(R.id.fl_left_container, subcategoriesFragment, TestActivity.TAG_SUBCATEGORIES_FRAGMENT); fragmentTransaction.commit();【参考方案3】:

就我而言

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

将创建完美的动画。

slide_in_right

<?xml version="1.0" encoding="utf-8"?>
<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 version="1.0" encoding="utf-8"?>
<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>

【讨论】:

我想自己做,但我太懒了。我说有人应该在 *** 上发布这个,就在这里!哈哈 以前没有人发过这个,我很相信是时候轮到我发这个答案了,帮助谁可能和我一样......哈哈@F.Mysir【参考方案4】:
.setCustomAnimations(R.animator.fragment_fade_in,
        R.animator.fragment_fade_out,
        R.animator.fragment_fade_p_in,
        R.animator.fragment_fade_p_out)

将以上内容替换为:

mFragmentManager.beginTransaction()
    .setCustomAnimations(R.animator.fragment_fade_in,
            R.animator.fragment_fade_out,
            R.animator.fragment_fade_p_in,
            R.animator.fragment_fade_p_out)
    .replace(R.id.main_container, FragmentPlayerInfo.getInstance(data))
    .addToBackStack(FragmentPlayerInfo.TAG)
    .commit();

【讨论】:

我建议您添加说明,说明您的建议有何帮助。 我不知道它为什么起作用(:,但是在replaceaddToBackstack之后添加动画时,不起作用 @TarikW 我来晚了,但是顺序很重要,你需要在替换之前调用 setCostomAnimations,addToBackStack 方法【参考方案5】:

这在 Fragment Transaction 类中提到。

/**
     * Set specific animation resources to run for the fragments that are
     * entering and exiting in this transaction. The <code>popEnter</code>
     * and <code>popExit</code> animations will be played for enter/exit
     * operations specifically when popping the back stack.
     *
     * @param enter An animation or animator resource ID used for the enter animation on the
     *              view of the fragment being added or attached.
     * @param exit An animation or animator resource ID used for the exit animation on the
     *             view of the fragment being removed or detached.
     * @param popEnter An animation or animator resource ID used for the enter animation on the
     *                 view of the fragment being readded or reattached caused by
     *                 @link FragmentManager#popBackStack() or similar methods.
     * @param popExit An animation or animator resource ID used for the enter animation on the
     *                view of the fragment being removed or detached caused by
     *                @link FragmentManager#popBackStack() or similar methods.
     */
    @NonNull
    public abstract FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int enter,
            @AnimatorRes @AnimRes int exit, @AnimatorRes @AnimRes int popEnter,
            @AnimatorRes @AnimRes int popExit);

所以最后你可以使用这样的方法

 mFragmentManager.beginTransaction()
                        .replace(R.id.container, fragment)
                        .setCustomAnimations(R.anim.slide_left,//enter
                                             R.anim.slide_out_left,//exit
                                             R.anim.slide_right,//popEnter
                                             R.anim.slide_out_right)//popExit
                        .addToBackStack(fragment.toString())
                        .commit();

【讨论】:

【参考方案6】:

这对我有用!!这段代码片段!如果你想在activity中使用这个代码,删除开头的getActivity()!!

getActivity().getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.fade_out,android.R.anim.slide_in_left, android.R.anim.fade_out)
        .replace(R.id.fragment_container, new YourFragment)
        .addToBackStack(null)
        .commit();

祝你好运!!

【讨论】:

以上是关于如何在 BackStack 上反转片段动画?的主要内容,如果未能解决你的问题,请参考以下文章

导航抽屉backstack,如何让actionbar标题在点击后随片段改变

当我们在android中使用backstack返回上一个片段时,上一个片段正在重新启动

Android TabLayout ViewPager 不会在 backstack 上膨胀标签片段

获取 backstack 中的最新片段

Android Reorder Fragment Backstack

以编程方式返回到 backstack 中的上一个片段