Jon*_*han 23 java android android-fragments
在管理Fragments时,我在应用程序中遇到了一些奇怪的行为,我想知道是否可以帮助解释为什么会发生这种情况.
我有两个片段,我们将它们称为片段A和片段B.我的应用程序的一般流程是当用户以某种方式与片段A交互时,片段B通过调用显示fragmentTransaction.replace()(这在所有情况下都会发生).当我显示片段B时,我将片段A添加到后栈; 然后,当用户按下片段B上的后退按钮时,片段A将通过从后面的堆栈弹出再次显示.
这一切都很好,但今天我发现有一个来自Fragment B的流调用fragmentTransaction.replace(),用当前在后栈上的Fragment A的相同实例替换Fragment B.
本身并没有什么不妥,但是当我从片段A回到片段B时会出现奇怪的行为.如果我打电话fragmentTransaction.replace(),onCreate()片段B 的方法就不会被调用.
但是,如果我从后面的堆栈弹出Fragment A然后用Fragment B替换它,则会释放Fragment B的onCreate()方法.为什么是这样?
请注意,片段A和片段B的所有实例都是在其主机活动启动时创建的.
编辑以澄清.onCreate()第二次调用的情况如下:将片段A =>替换为片段B,将片段A添加到后栈=> pop片段A使用popBackStack()=>将片段A再次替换为片段B.
min*_*deh 80
replace() 做两件事:
这两个操作是保存为Backstack记录/事务的操作.请注意,片段A保持created状态,并且其视图被销毁.
现在popBackStack()撤消您添加到BackStack的最后一笔交易.
在这种情况下,这将是两个步骤:
在此之后,片段B变为detached,如果您没有保留对它的引用,它将被垃圾收集.
要回答你问题的第一部分,没有onCreate()电话,因为FragmentB仍处于created状态.回答问题的第二部分有点长.
首先,重要的是要了解您实际上没有添加Fragments到Backstack,您添加FragmentTransactions.因此,当您认为"替换为片段B,将片段A添加到后台"时,您实际上将此整个操作添加到后台堆栈 - 即将A 替换为B.此替换包含2个操作 - 删除A并添加B .
然后,下一步是弹出包含此替换的事务.所以你没有弹出FragmentA,你正在反转"删除A,添加B",反之则是"删除B,添加A".
然后最后一步应该更清楚 - FragmentManager没有意识到B,所以当你在最后一步用A替换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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33289 次 |
| 最近记录: |