【问题标题】:Replacing a fragment in a FrameLayout does not remove the existing fragment from the fragmentManager替换 FrameLayout 中的片段不会从片段管理器中删除现有片段
【发布时间】:2015-08-11 00:55:34
【问题描述】:

我正在像这样动态添加一个片段:

        FragmentManager fm = getChildFragmentManager();
        mFragmentManager.beginTransaction().replace(R.id.learn_detail, detailFragment, LEARN_FRAGMENT_THREATS).commit();
        mFragmentManager.executePendingTransactions();

当我添加不同的片段 R.id.learn_detail(这是一个 Framelayout)时,我调用了相同的代码

片段被替换得很好,但我注意到旧片段仍然存在于内存中。

每次调用replace 时,调用mFragmentManager.getFragments 都会返回一个越来越大的列表。我希望replace 销毁旧片段并在 FrameLayout 中添加新片段。想法?

编辑 - 我的问题是我总是在创建一个新片段,无论如何。我的完整方法最终看起来像这样:

private LearnPageFragment getPageFragment(LearnPageItem item) {
    LearnPageFragment learnPageFragment = (LearnPageFragment) mFragmentManager.findFragmentByTag(LEARN_FRAGMENT_PAGE);

    if (learnPageFragment == null) {
        learnPageFragment = LearnPageFragment.newInstance(item);
    } else {
        //Destroy the view and update the item data
        mFragmentManager.beginTransaction().remove(learnPageFragment).commit();
        mFragmentManager.executePendingTransactions();
        learnPageFragment.getArguments().putSerializable(LearnPageFragment.k_CONTENT, item);
    }
    return learnPageFragment;
}

我接受了让我走上正轨的答案。我不应该尝试从片段管理器中手动删除片段。

【问题讨论】:

  • 您应该先删除现有的 Fragment 并添加新的 Fragment 而不是使用 replace。 :) 这是我的想法。
  • 这不是替换的作用吗?立即测试您的建议。

标签: android android-fragments


【解决方案1】:

FragmentManager 从 UI 中删除片段时,片段本身仍由FragmentManager 管理。除了完成它的活动之外,我不知道有什么方法可以专门告诉FragmentManager“忘记”一个片段。

期望您将重复使用已创建的片段,而不是一遍又一遍地实例化一个新片段。例如,使用标记参数调用FragmentTransaction.add(),然后调用FragmentManager.findFragmentByTag() 以获取对片段的引用。

【讨论】:

  • 我认为这是正确答案的轨道。每次点击时我都会创建一个新的片段,并且我没有检查 savedInstanceState 包是否为空。我将进一步解决这个问题并回复您。
【解决方案2】:

在 Android 中,Fragment 后台堆栈是自动管理的。不管你替换或添加Fragment,它都会被添加到Fragment back-stack。

解决您的问题的一种方法是,您可以在每次想要替换 Fragment 时清除您的回栈。

在您的代码中添加以下行。

FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)

所以你的代码看起来像

FragmentManager fm = getChildFragmentManager();
FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
mFragmentManager.beginTransaction().replace(R.id.learn_detail,  detailFragment, LEARN_FRAGMENT_THREATS).commit();
mFragmentManager.executePendingTransactions();

【讨论】:

  • 有趣。所以即使你调用了.addToBackStack(),片段也会被添加到后台堆栈中?编辑 - 我现在正在测试您的建议,感谢您的回复
猜你喜欢
  • 2023-03-21
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
相关资源
最近更新 更多