不出现闪烁的情况下管理Fragment返回栈流程

10
  1. 我创建了一个 AppCompatActivity 打开的 Fragment A->B->C->D->E->F,使用 replace()。
  2. 我现在在 F 页面,当我按下按钮时,我想清除 C 页面及其之前所有的页面,并打开 G 页面并放在 C 的顶部,所以新的页面顺序是 A->B->C->G。我可以通过 popBackStackImmediate() 清除 C 页面及其之前的所有页面,并使用 replace() 方法添加 G 页面到 C 的顶部。

问题:当我按下按钮时,我会看到 C 页面一闪而过,然后 G 页面显示在上面。为了防止这种情况发生,我尝试使用答案停止动画,但即使对于 fragment 已经停止了动画,C 仍然会在页面上一闪而过。

有没有更好的方法来设计 fragment 的流程或者解决在 C 页面之上替换 fragment 时出现闪烁的问题?


1
我最近一直在尝试弄清楚那个问题。禁用动画只会禁用交易动画,而不是交易本身,就我所知。 - kazume
我认为先替换片段,然后清除返回堆栈就可以解决问题了! - Rushabh Shah
嘿,你尝试过下面的答案了吗?还是仍然遇到问题? - 44kksharma
仅代表个人观点:在第一个Activity中放置A、B、C,然后在第二个Activity中放置D、E、F、G。当到达C时,如果仍需要C,则可以使用popBackStackImmediate()方法;或者在启动第二个Activity后结束第一个Activity。 - Iqbal Rizky
2个回答

4

我非常好奇这个问题,所以我创建了一个示例项目,并实现了你在问题中提到的相同用例。这是我的处理方法。

使用这种方法从后退栈中移除 F、E、D 片段。

private void removeFragments() {
    getSupportFragmentManager().popBackStack("F", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    getSupportFragmentManager().popBackStack("E", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    getSupportFragmentManager().popBackStack("D", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

使用此方法替换片段

private void replaceNewFragment(String key) {
    getSupportFragmentManager().beginTransaction().addToBackStack(key)
            .replace(android.R.id.content, AFragment.newInstance(key)).commit();
}

这里是一个视频演示。 在此输入图像描述

这个项目的完整内容可以在github上找到。


1

更通用的解决方案,针对这种导航流程,可以像这样替换片段

getSupportFragmentManager().beginTransaction().
                  replace(R.id.f_container,new FragmentA())
                    .addToBackStack("A")
                    .commit();
getSupportFragmentManager().beginTransaction().
                  replace(R.id.f_container,new FragmentB())
                    .addToBackStack("B")
                    .commit();

同样的方法一直做到片段F,假设您在F上有提交按钮 现在在提交按钮的onClick中

使用POP_BACK_STACK_INCLUSIVE标志将堆栈弹回到D,如下所示,并用片段G替换容器

getActivity().getSupportFragmentManager().popBackStack("D",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().
                      replace(R.id.f_container,new FragmentG())
                        .addToBackStack("G")
                        .commit();

现在,当您按下“返回”按钮时,您将看到Fragment C。
我希望这可以帮助您,对我而言它有效。

这对我有效。诀窍是使用popBackStack()而不是popBackStackImmediate(),并将所有内容捆绑在一个单独的“commit”中,就像44kksharma建议的那样。 - kazume
是的,诀窍是使用popBackStack而不是popBackStackImmediate,但问题是当我们使用popBackStack时,它会播放动画,如果我们在显示Fragment G时将滑动动画设置为Fragment C的弹出动画,那么看起来很奇怪。 - Kirtan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接