【问题标题】:How to avoid re-creation of fragment A when i go from fragment A to B and then back from fragment B to A当我从片段 A 到 B 然后从片段 B 回到 A 时,如何避免重新创建片段 A
【发布时间】:2021-03-25 09:32:13
【问题描述】:

当我从片段 B 回到片段 A 时,我想避免重新创建片段。

点击流:A->B

返回按钮:B->A

(在这种情况下,片段A被重新创建如何保存片段A的状态。)

【问题讨论】:

  • 你在关注任何架构组件吗?或使用片段交易
  • 分片交易。

标签: java android android-fragments fragment android-fragmentactivity


【解决方案1】:

目前还不清楚为什么您需要保留一个实例来存储不再可见的 Fragment;大概重新创建它很昂贵,所以你想保存它。

在大多数情况下,这是一种代码气味(但由于我不知道您的原因,也没有看过您的代码,所以我会给您怀疑的好处):)

假设您有正当理由,Android 会为 Fragments 提供一种保留机制:

直接来自Android的Fragment源码:

/**
     * Control whether a fragment instance is retained across Activity
     * re-creation (such as from a configuration change). If set, the fragment
     * lifecycle will be slightly different when an activity is recreated:
     * <ul>
     * <li> {@link #onDestroy()} will not be called (but {@link #onDetach()} still
     * will be, because the fragment is being detached from its current activity).
     * <li> {@link #onCreate(Bundle)} will not be called since the fragment
     * is not being re-created.
     * <li> {@link #onAttach(Activity)} and {@link #onActivityCreated(Bundle)} <b>will</b>
     * still be called.
     * </ul>
     */
    public void setRetainInstance(boolean retain) {

请记住这样做的影响,因为现在您的生命周期是不同的,期待正常生命周期的所有副作用(以及保留片段的内存影响)也是如此。

或者,考虑将 Fragment 的状态与其分离到 ViewModel、Repository 或 Beyond™ 中,并让 Fragment 被简单地告知其状态,以便可以以“快速”和“高效”的方式正确地重新创建它。 (我引用这些是因为旁观者认为快速/高效,而且它仍然受制于 Android 规则......)。

现在,我还没有看到您如何“导航”以及如何“返回”,因此您必须自己进行测试。最终,如果 FragmentManager 想要销毁您的 Fragment,可能是因为它没有理由保留它(您可以保留硬引用并处理所有浪费的内存......这就是为什么我建议您保留“状态" 而不是在 Fragment 之外,因为创建一个 Fragment 并不昂贵,如果 Fragment 在 onCreate 中不包含 2000 行代码...) :)

【讨论】:

【解决方案2】:

假设您要从类别片段转到子类别片段。当事务像这样发生时,您必须将当前片段添加到后台堆栈 -

val fragmentManager: FragmentManager? = fragmentManager
    val fragmentTransaction: FragmentTransaction? = fragmentManager?.beginTransaction()

    val fragment = SubCategoryFragment()
    fragment.arguments = bundle
    fragmentTransaction?.replace(R.id.container_fragment, fragment)
    fragmentTransaction?.addToBackStack("category")
    fragmentTransaction?.commit()

这里 fragmentTransaction?.addToBackStack("category") 行将当前片段添加到后台堆栈。

最后,您想从子类别返回类别片段,如下所示,

 fragmentManager?.popBackStack()

它会回忆上一个片段。

这段代码在 kotlin 中,但我想你会理解解决方法。

【讨论】:

  • 但是在这种情况下,片段仍然会被销毁,不是吗?所有的后台添加都是保存事务,因此可以反向完成(例如,当您回击时)但与保留片段实例无关......我在这里遗漏了什么吗?
  • 是的,这种情况下碎片也会被销毁。
  • 是的,你是对的,实际上,不清楚提问者真正想要什么。我刚刚对最常见的情况给出了一个概括的答案。让我们看看其他人怎么说。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多