弹出片段backstack而不播放Pop-Animation

Chr*_*phK 55 android android-animation android-fragments

我使用以下代码在片段堆栈上推送片段:

FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right,
     R.anim.slide_in_left, R.anim.slide_out_left);
fragmentTransaction.replace(getId(), newFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)

这样,当弹出片段堆栈时,例如通过按下后退按钮,播放片段弹出动画.但是,有些情况下我想在不显示此动画的情况下弹出片段backstack,例如因为我刚刚从另一个活动返回并希望一次显示前一个片段,而没有动画.

示例导航可能如下所示:

  • 用户在根屏幕的开始屏幕上
  • 他在根片段上选择一个项目,然后显示一个新片段以显示该项目的详细信息.它使用片段事务来设置推送和弹出案例的动画(因此当用户按下后退按钮时,过渡动画)
  • 从这个片段开始,他开始一个活动(无论出于何种原因)删除刚刚显示的项目
  • 当这个活动结束时,我想返回根片段而不显示"细节片段"的"流行动画"

有没有办法弹出片段backstack而不播放指定的流行动画?

Geo*_*off 87

所以Warpzit走在正确的轨道上,他只是没有很好地解决你的具体问题.我遇到了完全相同的问题,这就是我如何解决它.

首先,我创建了一个静态布尔变量(为简单起见,让它放在FragmentUtils类中)...

public class FragmentUtils {
    public static boolean sDisableFragmentAnimations = false;
}
Run Code Online (Sandbox Code Playgroud)

然后,在你拥有的每个片段中,你需要覆盖onCreateAnimation方法......

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (FragmentUtils.sDisableFragmentAnimations) {
        Animation a = new Animation() {};
        a.setDuration(0);
        return a;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}
Run Code Online (Sandbox Code Playgroud)

然后,当您需要从活动中清除背斜时,只需执行以下操作...

public void clearBackStack() {
    FragmentUtils.sDisableFragmentAnimations = true;
    getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    FragmentUtils.sDisableFragmentAnimations = false;
}
Run Code Online (Sandbox Code Playgroud)

瞧,对clearBackStack()的调用会让你回到根片段而没有任何过渡动画.

希望大G将在未来添加一种不那么愚蠢的方式.

  • 这可以工作,但片段仍然会出现一个简短的框架.有没有办法让它不显示? (8认同)
  • +1必须牢记这只适用于popBackStackImmediate(它不适用于popBackStack). (8认同)
  • 为了使用常规版本的popBackStack(而不是popBackStackImmediate),你必须避免"取消设置"FragmentUtils.sDisableFragmentAnimations标志,直到片段实际被弹出(即你需要某种回调来取消它). (4认同)

500*_*865 6

用户在根屏幕的开始屏幕上

让我们说根片段包含在活动A中.

他在根片段上选择一个项目,然后显示一个新片段以显示该项目的详细信息.它使用片段事务来设置推送和弹出案例的动画(因此当用户按下后退按钮时,过渡动画)

该事务被添加到后台堆栈.这意味着当从细节片段按下后退按钮时,弹出过程是动画的.

从这个片段开始,他开始一个活动(无论出于何种原因)删除刚刚显示的项目.

让我们说这是活动B.

当这个活动结束时,我想返回根片段而不显示"细节片段"的"流行动画"

获得此行为的一种方法是在活动B中执行此操作:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
Run Code Online (Sandbox Code Playgroud)

这将启动活动A根据文档将其重置为其根状态.(检查"此启动模式也可以与FLAG_ACTIVITY_NEW_TASK结合使用效果良好的部分中的最后一段:......" )

使用此配置,动画将以默认情况显示,而在特殊情况下,您可以使用以下命令控制动画:

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
Run Code Online (Sandbox Code Playgroud)

在没有任何动画的情况下开始新活动.如果你想要任何动画,你可以使用该overridePendingTransition方法.


War*_*zit 6

所以对于以下工作的支持库:

在应该具有自定义弹出动画的片段中,您可以使用自己的自定义动画覆盖onCreateAnimation.您可以根据自己的需要获取并设置某种参数.可能需要做一些额外的工作才能使它与常规片段一起工作.

这是我覆盖它并更改设置持续时间的示例:

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    Animation anim = (Animation) super.onCreateAnimation(transit, enter, nextAnim);
    if(!enter) {
        if(anim != null) {
            anim.setDuration(0); // This doesn't seem to be called.
            return anim;
        } else {
            Animation test = new TestAnimation();
            test.setDuration(0);
            return test;
        }
    }
    return anim;
}

private class TestAnimation extends Animation {

}
Run Code Online (Sandbox Code Playgroud)


Arc*_*nes 5

Android 现在实际上有一种方法可以做到这一点,而无需绕过 @Geoff 的回答。

为了避免动画运行popBackStack(),在膨胀你的fragments 时添加.setReorderingAllowed(true)到你的fragmentTransaction.

例如:

supportFragmentTransaction.beginTransaction()
    .setReorderingAllowed(true)
    .addToBackStack(null)
    .setCustomAnimations(
        android.R.anim.fade_in,
        android.R.anim.fade_out,
        android.R.anim.fade_in,
        android.R.anim.fade_out
    )
    .replace(yourContainer.id, yourFragment)
    .commit()
Run Code Online (Sandbox Code Playgroud)

您会注意到,如果设置setReorderingAllowed(true),弹出动画将不再播放。结果实际上与@Geoff的回答结果类似。