如何popBackStack()和替换()操作有什么不同? [英] How do popBackStack() and replace() operations differ?

查看:1585
本文介绍了如何popBackStack()和替换()操作有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

管理片段时,我遇到了我的应用程序的一些奇怪的行为,我想知道如果这样可以帮助一些启发到为什么会这样。

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.

推荐答案

更换()做两件事情:

  1. 从容器(C)你表示删除当前添加的片段(A)
  2. 添加新的片段(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:

  1. 从C删除乙
  2. 系统加入到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆