Android碎片:何时使用隐藏/显示或添加/删除/替换?

126

如果我想要用另一个片段替换某个容器视图中的当前片段,那么使用replace...更好吗?

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, null);
    ft.commit();

...或以下,带有显示和隐藏?

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.hide(oldFragment);
    ft.show(newFragment);
    ft.commit();

有没有更有效率的做法?找不到很多关于何时使用这些方法以及它们如何影响所涉片段的生命周期的信息。 谢谢!


如果我从片段A转到片段B,然后返回到片段A,如何确保不会在片段A上调用onCreateView等生命周期事件?通过标签查找片段是否有效? - blackHawk
4个回答

149

为了决定哪种方式更适合你的需求,你应该考虑你想对碎片做什么。如果你使用FragmentTransaction把碎片隐藏起来,那么它可能仍然在其生命周期的运行状态中,但是它的UI已经从窗口中分离出来,因此不再可见。所以你可以在技术上与碎片进行交互,并在需要时重新附加它的UI。如果你替换该碎片,那么你实际上是将它从容器中移除,并且它将遵循生命周期中的所有拆卸事件(例如onPause、onStop等),如果出于某种原因你需要该碎片,你将不得不将其插入回容器中,并让它重新运行其所有的初始化。

如果高概率会再次需要该碎片,则只需将其隐藏,因为重绘其布局比完全重新初始化要廉价得多。


6
根据我们的需求,初始化该片段的成本相当高,因此我们可能会选择使用“hide()”和“show()”来节省成本!感谢您提供这个建议! - Robert Karl
2
你好,当你说从窗口分离时,是指会调用onDetach()回调函数吗?我进行了实验,似乎并不是这种情况。 - GingerJim
可能他的意思是“分离”;片段也可以被分离/重新连接(除了添加/删除、显示/隐藏之外)。 - comeGetSome
1
@Zainodis,我也有同样的问题。我的解决方案是在onSaveInstanceState()中保存片段的隐藏状态 - savedInstanceState.putBoolean(STATE_HIDDEN, isHidden());然后在onCreate()中,如果savedInstanceState不为空,则获取隐藏状态,并且如果片段被隐藏,则使用事务将其隐藏。 - worawee.s
1
@worawee.s 你好,感谢更新 :)!我一段时间前已经解决了我的问题 - 我实际上并不需要隐藏/显示等等。所以我完全放弃了它,现在我采用标准的add/replace或单片段活动在单窗格(主细节流)中进行。对于那些仍在使用hide的人,你的解决方案将非常有帮助 - 而且在之前我犯的错误之一是没有检查savedInstance != null。 - AgentKnopf
显示剩余3条评论

5
你其实已经给出了答案。如果你想要替换(使旧的片段不再需要),使用replace(),如果你想要暂时隐藏它,则使用hide()

基本上用 removeAll 替换。我找不到匹配的 hideAll :( - AlikElzin-kilaka
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mansukh Ahir

1
如果视图较“重”,我认为应使用隐藏/显示。有这样的回调函数:onHiddenChanged。如果您使用隐藏/显示,会很有帮助。

0

我在我的活动中使用了Hide/Show方法,其中包含4个片段,这解决了我的问题,但有时随机地显示对话框时会出现窗口错误令牌异常。当我使用添加和替换方法时,就不会发生错误令牌异常,因此我认为Show/Hide方法并不完美。


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