片段 popbackstack 行为在 25.1.0 和 25.1.1 中被破坏

Posted

技术标签:

【中文标题】片段 popbackstack 行为在 25.1.0 和 25.1.1 中被破坏【英文标题】:fragment popbackstack behaviour broken in 25.1.0 and 25.1.1 【发布时间】:2017-06-19 14:36:07 【问题描述】:

由于支持版本 25.1.0 和最新的 25.1.1,我在片段替换/添加时遇到了奇怪的行为。 已报告 25.1.0 android - fragmentTransaction.replace() not works on support library 25.1.0 的问题

但现在在 25.1.1 中我遇到了类似的问题。为了重现我创建的示例应用程序的行为,您可以在https://github.com/holoduke/fragmenttest找到它

它基本上是一个带有片段容器的 Activity。有几个片段可用,它们将通过按下按钮动态地相互替换。我们首先从 mainActivity 本身添加 FragmentA。

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();

    Fragment f = new FragmentA();
    fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    f.setRetainInstance(false);
    ft.replace(R.id.fragmenttarget, f);
    ft.addToBackStack(null);
    ft.commit();

一切都很好 工作正常。在 25.0.1、25.1.0 和 25.1.1 中

现在在fragmentA中有3个按钮,它们都将用fragmentA、fragmentB或fragmentC替换当前的fragment

添加片段B和C的代码与片段A几乎相同,只是我们没有定义:

fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

当添加片段 B 或 C 时,将执行以下代码:

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();

    Fragment f = new FragmentB();
    f.setRetainInstance(false);
    ft.replace(R.id.fragmenttarget, f);
    ft.addToBackStack(null);
    ft.commit();

在 25.0.1、25.1.0 和 25.1.1 中仍然一切正常。 如果您添加 fragmentB 和 C 几次 fm.getBackStackEntryCount() 正在增加。很好。

现在是奇怪的部分。 我们想用 popStackImmediate 添加 FragmentA(清除历史记录) 在这里,两个支持版本的行为都变得疯狂。

假设您在所有 3 个版本中执行以下操作:

    启动应用程序 替换为片段 B 用片段 C 替换 替换为片段 B 用片段 C 替换 替换为片段 A

在 25.0.1 中一切正常。后台堆栈被清除,在 FragmentA 中调用 onCreateView 和 ActivityCreated。

在 25.1.0 中,在用 FragmentA 替换后,onCreateView 和 ActivityCreated 被调用了 2 次。不好。

在 25.1.1 中情况更糟。替换为 fragmentA 后,对于 backstack 中的所有视图,将调用 onCreateView 和 ActivityCreated。现在这很有趣:)

只需试用我的示例应用程序并查看 logcat。更改 app.gradle 文件中的支持版本以查看差异。

如果有人也能认识到这个问题,我会很高兴,这样我们就可以找到克服甚至解决这个问题的方法。

【问题讨论】:

您是否要从Fragment 本身替换Fragment?如果是这样,请使用getChildFragmentManager() - 只需要澄清一下。 没有从 MainActivity 替换它。见github.com/holoduke/fragmenttest/blob/master/app/src/main/java/… 我确认当弹出到堆栈更深处的片段时,其间的所有片段都会在 25.1.1 中调用其 onCreateView。这破坏了我的应用程序,该应用程序在更新到 25.1.1 之前运行良好。降级到 25.1.0 解决了我的问题。但是,我的替换方式类似于 A->B->C->D,这与您的示例不同,因此我可能没有遇到您在 25.1.0 中提到的问题。 【参考方案1】:

好吧,我遇到了同样的问题,通过比较 25.0.1 -> 25.1.1 FragmentManager.class 找到了解决方案。尝试使用 FragmentTransaction 的 setAllowOptimization 方法。

【讨论】:

以上是关于片段 popbackstack 行为在 25.1.0 和 25.1.1 中被破坏的主要内容,如果未能解决你的问题,请参考以下文章

在 PopBackStack 之后片段弹出调用 OnViewCreated

PopBackStack 但将第一个片段保留在 android

如何知道何时调用了`navController.popBackStack()`?

BottomNavigation popBackStack() 导航到 startDestination 而不是上一个片段

popBackStack导致一次又一次调用片段的oncreateView

FragmentManager popBackStack 不删除片段