当我从片段 A 到 B 然后从片段 B 返回到 A 时,如何避免重新创建片段 A

时间:2021-03-25 09:32:13

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

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

点击流::Business

返回按钮:A->B

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

2 个答案:

答案 0 :(得分: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 行代码...) :)

答案 1 :(得分:0)

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

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 中,但我想你会理解解决方法。