如何popBackStack()和替换()操作有什么不同? [英] How do popBackStack() and replace() operations differ?
问题描述
管理片段时,我遇到了我的应用程序的一些奇怪的行为,我想知道如果这样可以帮助一些启发到为什么会这样。
I've encountered some curious behavior in my application when managing Fragments and I was wondering if SO could help shed some light onto why this happens.
我有两个片段,我们会打电话给他们的片段A和片段B.我的应用程序的一般流程是,当用户以某种方式与片段A相互作用,片段B表示通过调用 fragmentTransaction.replace()
(这种情况在所有情况下)。当我告诉片段B,我想补充片段A到后面栈;然后,当用户presses的片段B后退按钮,片段A被再次从后面堆栈弹出如图所示。
I have two Fragments, we'll call them Fragment A and Fragment B. The general flow of my application is that when the user interacts with Fragment A in some way, Fragment B is shown by calling fragmentTransaction.replace()
(this happens in all cases). When I show Fragment B, I add Fragment A to the back stack; then, when the user presses the back button on Fragment B, Fragment A gets shown again by popping from the back stack.
这是一切都很好,但今天我发现,有一个从片段B流动这就要求 fragmentTransaction.replace()
,具有相同的实例替换片段B片段A是目前后退堆栈。
That's all well and good, but today I discovered that there is a flow from Fragment B which calls fragmentTransaction.replace()
, replacing Fragment B with the same instance of Fragment A that is currently on the back stack.
在和本身没有什么错,但是奇怪的现象出现时,我从片段A回片段B.如果我叫 fragmentTransaction.replace()
,片段B的的onCreate()
方法不叫。
In and of itself there's nothing wrong with that, however the strange behavior arises when I go back from Fragment A into Fragment B. If I called fragmentTransaction.replace()
, the onCreate()
method of Fragment B is not called.
不过,如果我突然出现一个片段从后面堆栈中,然后用片段B取而代之,片段B的的onCreate()
方法被激发。这是为什么?
However, if I popped Fragment A from the back stack and then replaced it with Fragment B, the onCreate()
method of Fragment B is fired. Why is this?
注意,片段A和片段B的所有实例在其主机活动启动时创建的。
Note that all instances of Fragment A and Fragment B are created at the time their host Activity is launched.
编辑进行澄清。其中,的onCreate()
被称为第二次的情况如下:将片段A =>与片段B取代,加入片段A到后面堆栈=>弹出片段A使用 popBackStack()
=>替换片段A和片段B了。
Edit for clarification. The case where onCreate()
is called a second time is the following: Attach Fragment A => replace with Fragment B, adding Fragment A to the back stack => pop Fragment A using popBackStack()
=> replace Fragment A with Fragment B again.
推荐答案
更换()
做两件事情:
- 从容器(C)你表示删除当前添加的片段(A)
- 添加新的片段(B)到同一个容器
这两个操作是怎样被保存为Backstack记录/交易。需要注意的是片段A保持在创建
状态,其观点被破坏。
These 2 operations are what is saved as a Backstack record / transaction. Note that fragment A remains in created
state, and its view is destroyed.
现在 popBackStack()
反转你,你已经加入到BackStack最后一笔交易。
Now popBackStack()
reverses your last transaction that you've added to BackStack.
在这种情况下,这将是2个步骤:
In this case that would be 2 steps:
- 从C删除乙
- 系统加入到C
在此之后,B片段变成分离
,如果你不保持对它的引用,这将是垃圾收集。
After this, fragment B becomes detached
, and if you did not keep references to it, it will be garbage collected.
要回答你的问题的第一部分,有没有的onCreate()
通话,因为FragmentB留在创建
状态。而问题的答案的第二部分是多一点的时间。
To answer first part of your question, there's no onCreate()
call, because FragmentB remained in created
state. And answer to second part of the question is a bit longer.
首先,要明白,你不实际添加片段
来Backstack是很重要的,您可以添加 FragmentTransactions
。所以,当你认为你与片段B取代,加入片段A到后面栈,你实际上添加这整个操作backstack - 这是的替换的A和B的这种替换包括2操作 - 删除和加入乙组
First, it is important to understand that you don't actually add Fragments
to Backstack, you add FragmentTransactions
. So when you think that you "replace with Fragment B, adding Fragment A to the back stack", you actually add this whole operation to backstack - that is replacement of A with B. This replacement consists of 2 actions - remove A and add B.
然后,下一步是弹出包含此置换交易。所以,你不弹出碎裂,你在倒车中删除,加入B,这扭转的删除B,新增A。
Then, next step is popping of the transaction that contains this replacement. So you're not popping FragmentA, you're reversing "remove A, add B", which reversed is "remove B, add A".
然后最后一个步骤应该是清晰的 - 有没有B中FragmentManager是知道的,所以当你通过你的最后一步,为B更换添加它,B需要经过早期的生命周期方法 - onAttach()
和的onCreate()
。
And then final step should be clearer - there's no B that FragmentManager is aware of, so when you add it by replacing A with B at your last step, B needs to go through its early lifecycle methods - onAttach()
and onCreate()
.
code说明发生了什么。
Code below illustrates what is happening.
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()和替换()操作有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!