Fragment生命周期中add()和replace()的区别

21

我的程序有6个片段: Fragment1, Fragment2,...->Fragment6.

我使用add()和replace()语句在片段之间切换并跟踪它们的生命周期。

Fragment1 add Fragment2 add Fragment3 add Fragment4 add Fragment5 replace Fragment6

日志记录它们的生命周期 (我在onCreate、onCreateView、onDestroyView、onDestroy中有一些printf点来跟踪)


标签 ______________ 文本

Fragment1_________onCreate

Fragment1_________onCreateView

Fragment1_________添加Fragment2

Fragment2_________onCreate

Fragment2_________onCreateView

Fragment2_________添加Fragment3

Fragment3_________onCreate

Fragment3_________onCreateView

Fragment3_________添加Fragment4

Fragment4_________onCreate

Fragment4_________onCreateView

Fragment4_________添加 Fragment5

Fragment5_________onCreate

Fragment5_________onCreateView

Fragment5 _______ 替换为 Fragment6

Fragment1 _______ onDestroyView

Fragment3 _______ onDestroyView

Fragment5 _______ onDestroyView

Fragment6_________onCreate

Fragment6_________onCreateView


我的问题:

为什么在 Fragment5 被 Fragment6 替换后, Fragment1、3 和 5 的视图被销毁了?

Fragment2 & 4 发生了什么?

为什么 Fragment2 & 4 没有像 Fragment1、3 和 5 一样销毁它们的视图?

1. 当 Fragment5 被替换为 Fragment6 时,FragmentManager 将销毁 Fragment5 的视图并调用其 onDestroyView() 方法。这是因为 FragmentManager 认为 Fragment5 不再需要显示,因此可以释放其视图以减少资源占用。 2. Fragment2 & 4 的状态取决于它们是否与 Activity 关联。如果它们已经与 Activity 脱离关联,则它们的视图可能已经被销毁。否则,它们的视图仍然存在。 3. Fragment2 & 4 可能没有被销毁其视图,是因为它们被添加到了 back stack 中。当使用 back stack 返回到它们时,它们的视图将被恢复。

请帮助我充分了解调用add()和replace()方法时Fragment的生命周期。


更新我的addFragment和replaceFragment方法:

public void addFragment(Fragment fromFragment, Fragment toFragment) {
    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.container,toFragment, toFragment.getClass().getName());
    transaction.hide(fromFragment);
    transaction.addToBackStack(toFragment.getClass().getName());
    transaction.commit();
}

public void replaceFragment(Fragment fromFragment, Fragment toFragment) {
    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.container,toFragment, toFragment.getClass().getName());
    transaction.hide(fromFragment);
    transaction.addToBackStack(toFragment.getClass().getName());
    transaction.commit();
}

你能否更新你的问题,附上用于替换片段的代码以及替换片段的视图XML? - Ben Pearson
2个回答

7
如果您使用FragmentTransaction隐藏片段,则它仍然可以处于其生命周期的运行状态,但其UI已从窗口分离,因此不再可见。因此,您在技术上仍然可以与该片段交互并稍后重新附加其UI(如果需要)。如果替换该片段,则实际上是将其从容器中移出,并且它将经历生命周期中的所有拆除事件(onPauseonStop等),如果由于某种原因您需要该片段,则必须将其插入回容器中,并让它再次运行其所有初始化。

5
当您进行替换时,您正在将ViewGroupR.id.container中的所有片段(1,2,3,4,5)与新的Fragment(6)交换。一旦片段被移除,它们将被销毁。销毁时,它们将调用onDestroyView()方法。
关于您的第2和第4个问题,我不确定。您能否发布更多写入logcat的代码? FragmentTransaction replace

正如我之前提到的那样:在片段的每个方法 onCreate()、onCreateView()、onDestroyView() 和 onDestroy() 中,我都加入了一个简单的打印点来跟踪其生命周期。例如:onCreate(){ Log.d(Tag, onCreate); } - thanhnh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接