【问题标题】:Programmatically removing a ViewPager, when are (or how can I ensure) contained Fragments are destroyed?以编程方式删除 ViewPager,何时(或如何确保)包含的片段被销毁?
【发布时间】:2012-10-07 00:47:19
【问题描述】:

事先搜索过这个问题,我可以找到许多关于从ViewPager 动态添加和删除选定Fragments 的讨论。然而,我在这里真正关心的是,当ViewPager 已用于通过FragmentPagerAdapter 显示Fragments 时,我如何以编程方式从包含ViewGroup 中“干净地”删除整个ViewPager,并确保正确销毁包含的Fragments。

为了进一步扩展这个问题,我有一个横向两窗格布局,其中从左侧 Fragment 中的列表中进行选择,然后将选择的内容放在右侧在FrameLayout 内。关键是内容可能会或可能不会分页。因此,内容必须要么以ViewPager 格式显示,要么如果没有分页,则直接由单个Fragment 表示。

为了显示单个Fragment,我只需像往常一样执行FragmentTransaction,以便将Fragment 放入FrameLayout 容器中。另一方面,如果要显示分页内容,那么我创建一个ViewPager 并将其添加为FrameLayout 的子项。

当我需要更改内容时,如果之前的内容是独立的Fragment,那么我可以通过FragmentTransaction .remove() 将其删除。当我这样做时,Fragment 按预期经历onPause() ...onDestroy() 循环。如果之前的内容是ViewPager,那么我使用.removeAllViews() 将其从FrameLayout 中删除。这里我遇到了问题:我没有看到任何onPause() ... onDestroy() 方法在通过FragmentPagerAdapter 保存在ViewPager 中的任何Fragments 中被调用。

从用户的角度来看,该应用程序运行良好。经过几轮ViewPager被删除后,我可以看到GC回收内存。但是,我不喜欢没有调用那些 Fragments 的生命终结方法,因为我无法在其中进行任何清理,而且它看起来并不“正确”。

ViewPager 与其父级分离时,我是否可以使用一种方法来删除ViewPagerFragments?换句话说,当我知道ViewGroup 不再使用时,我会在某处(可能在FragmentPagerAdapter)执行FragmentTransactions 以删除那些Fragments。

另外,我意识到我可以将ViewPager 永久保留在右侧,并在其中动态交换Fragments。当然,在某些时候它只保留一页并不重要。如果这是一个更好的方法,那么我将重构我的代码来做到这一点,但我会很感激意见。

【问题讨论】:

    标签: android android-fragments android-viewpager


    【解决方案1】:

    但是,我不喜欢不调用那些 Fragments 的生命周期结束方法的事实,因为我无法在其中进行任何清理,而且看起来并不“正确”。

    它们应该在 Activity 被销毁时被清理,如果这对您来说还不算太晚(例如,堆问题)。

    换句话说,当我知道不再使用 ViewGroup 时,我会在某处(可能在 FragmentPagerAdapter 中)执行 FragmentTransactions 以删除这些 Fragment。

    您没有执行交易以将片段放在那里。因此,您不能轻易地执行事务来删除片段。如果您切换到FragmentStatePagerAdapter,并调用setAdapter(null),通过我阅读源代码,它应该会导致寻呼机中的所有现有片段被破坏。 FragmentPagerAdapter 从不使用remove(),但FragmentStatePagerAdapter 使用它的destroyItem() 方法,当一个新的适配器(或null)提供给setAdapter() 时,所有现存的片段都通过destroyItem() 销毁。

    【讨论】:

    • 谢谢。我刚才想到的一个解决方案是在destroyItem 中使用FragmentManager 来删除Fragment。我还从getItemPosition 返回PagerAdapter.POSITION_NONE 并致电notifyDataSetChanged()。通过在删除ViewPager 之前执行此操作,调用Fragments'onDestroy,我很高兴。你觉得这有什么问题吗?使用FragmentPagerAdapter 的原因是因为我希望所有Fragments(一小部分)都留在身边,因为我的UI 要求用户数据从所有片段中持久化以响应单个接受按钮操作。
    • @Trevor:“你觉得这有什么问题吗?” -- 这应该没问题,不过在对 Android 支持包进行任何更新时要小心。据我们所知,它们会改变行为,使得 Android 也会尝试销毁 Fragment,您可能会遇到错误并不得不退出您自己的销毁逻辑。
    • 再次感谢您,理解。似乎我现在拥有的是两全其美:使用FragmentPagerAdapter 意味着从Fragment 分页不会破坏它,但是通过扩展destroyItem 来删除片段就像FragmentStatePagerAdapter 一样,我可以需要时删除片段。 (我很欣赏要求所有附加的片段保留,以便我可以要求它们立即保存用户输入数据可能会令人不悦,但否则我将不得不重构,以便所有片段将此数据传递给主 Activity,我'宁愿避免。)
    • @Trevor 你能提供解决方案的代码吗?我将不胜感激谢谢
    猜你喜欢
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    相关资源
    最近更新 更多