popBackStack()和replace()操作有何区别?
在管理Fragments时,我的应用程序遇到了一些奇怪的行为,我想知道SO是否可以帮助我们弄清为什么会发生这种情况。
我有两个片段,我们将它们分别称为片段A和片段B。我的应用程序的一般流程是,当用户以某种方式与片段A交互时,通过调用显示片段B
fragmentTransaction.replace()
(在所有情况下都会发生)。当显示片段B时,我将片段A添加到后台堆栈中。然后,当用户按下片段B上的“后退”按钮时,通过从后退堆栈弹出,片段A再次显示。
很好,但是今天我发现片段B有一个流,该流调用fragmentTransaction.replace()
,用当前在后堆栈上的片段A的相同实例替换片段B。
它本身没有任何问题,但是,当我从片段A返回片段B时,会出现奇怪的行为。如果我调用fragmentTransaction.replace()
,onCreate()
则不会调用片段B
的方法。
但是,如果我从后堆栈中弹出片段A,然后将其替换为片段B,onCreate()
则会触发片段B的方法。为什么是这样?
请注意,片段A和片段B的所有实例都是在其主机活动启动时创建的。
编辑进行澄清。onCreate()
第二次被调用的情况如下:将Fragment A =>附加为Fragment B,将Fragment A添加到后堆栈=>
pop Fragment A中,使用popBackStack()
=>再次将Fragment A替换为FragmentB。
回答:
replace()
做两件事:
- 从您指定的容器(C)中删除当前添加的片段(A)
- 将新片段(B)添加到同一容器
这两个操作被保存为Backstack记录/事务。请注意,片段A保持created
状态,并且其视图已损坏。
现在,popBackStack()
撤消您添加到BackStack的上一个事务。
在这种情况下,这将是2个步骤:
- 从C中删除B
- 将A加到C
此后,片段B变为detached
,如果您不保留对其的引用,它将被垃圾回收。
要回答问题的第一部分,没有任何onCreate()
电话,因为FragmentB保持created
状态。对问题第二部分的回答要更长一些。
首先,重要的是要了解您实际上并没有添加Fragments
到Backstack中FragmentTransactions
。所以,当你认为你“与片段B取代,加入片段A到后面栈”,实际上添加这整个操作堆栈中-即
替代 与B. A的这种替换包括2个动作-删除和Add(添加) 。
然后,下一步是弹出包含此替换的事务。因此,您没有弹出FragmentA,而是反转了“删除A,添加B”,反过来就是“删除B,添加A”。
然后最后一步应该更清楚-FragmentManager不会知道B,因此当您在最后一步通过用B替换A来添加它时,B需要经历其早期生命周期方法-
onAttach()
和onCreate()
。
下面的代码说明了正在发生的事情。
FragmentManager fm = getFragmentManager();FragmentA fragmentA = new FragmentA();
FragmentB fragmentB = new FragmentB();
// 1. Show A
fm.beginTransaction()
.add(fragmentA, R.id.container)
.commit();
// 2. Replace A with B
// FragmentManager keeps reference to fragmentA;
// it stays attached and created; fragmentB goes
// through lifecycle methods onAttach(), onCreate()
// and so on.
fm.beginTransaction()
.replace(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
// 2'. Alternative to replace() method
fm.beginTransaction()
.remove(fragmentA)
.add(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
// 3. Reverse (2); Result - A is visible
// What happens:
// 1) fragmentB is removed from container, it is detached now;
// FragmentManager doesn't keep reference to it anymore
// 2) Instance of FragmentA is placed back in the container
// Now your Backstack is empty, FragmentManager is aware only
// of FragmentA instance
fm.popBackStack();
// 4. Show B
// Since fragmentB was detached, it goes through its early
// lifecycle methods: onAttach() and onCreate().
fm.beginTransaction()
.replace(fragmentB, R.id.container)
.addToBackstack(null)
.commit();
以上是 popBackStack()和replace()操作有何区别? 的全部内容, 来源链接: utcz.com/qa/419053.html