片段 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 而不是上一个片段