当返回到父片段时,ViewPager2 中的片段会被重新创建。

8

我在一个Fragment中(称之为A Fragment)使用了ViewPager2,它使用了FragmentStateAdapter来创建一些子Fragment(我们称之为children)。当用户在A Fragment中点击一个按钮后,我将其替换为B Fragment。

现在,当用户点击设备的返回按钮回到A Fragment时,我发现系统会自动还原children(它们不会显示在ViewPager中,但是它们的onCreateView方法被调用并且保存的Bundle被传递给它们)。如何避免这种行为?我不希望children被自动重新创建和恢复。


您有一个包含N个子项的ViewPager的容器(A)。然后,您将此容器(A)替换为另一个容器(B)。这意味着ViewPager中的所有片段(子项)都已消失,因为它们的父项(A)现在已经不存在了。您到底希望发生什么?您不可能希望将所有ViewPager子项保留在内存中,这将是潜在的浪费(更不用说您可能没有那么多内存)。那么问题出在哪里呢? - Martin Marconcini
@MartinMarconcini,问题在于当我通过点击后退按钮从后退栈中弹出片段A时,ViewPager的片段会自动重新创建(它们的onCreateView方法会被调用)。我不明白为什么会发生这种情况,也不知道如何避免。 - Soheil
ViewPager是一个视图(事实上,ViewPager2基本上是一个RecyclerView)。当片段被弹出/隐藏/移除时,其视图会被销毁以释放资源,这自然包括该视图的子项。这就是片段的工作原理。如果您想保留它们的状态,则可以这样做,然后在重新创建视图时恢复状态。试图防止片段销毁其视图并不是一个好主意。 - Martin Marconcini
@MartinMarconcini 我认为你误解了问题。当我替换片段A时,我确实希望所有子项(包括viewpager)都被销毁。但是当我回到片段A时,我发现即使在保存viewpager中的任何项目之前,viewpager中的片段的onCreate方法也被调用了。为什么?!在我还没有向viewpager添加任何数据的情况下,谁实例化了这些片段?! - Soheil
确实,我误解了它;那么你能分享一下创建ViewPager的代码吗?如果ViewPager被创建,它将与一个适配器相关联,并触发其offscreenPageLimit的创建,但我相信其中还有更多的东西。我相信VP或FragmentManager正在"预先智能化"并准备恢复先前的状态。 - Martin Marconcini
2个回答

5
简而言之,ViewPager 保持一个内部项目列表(代表“页面”)。此列表中的项目数量基于 mOffScreenPageLimit 值。默认情况下,它设置为1,但您可以通过调用 setOffscreenPageLimit (int limit) 来更改它。 例如:
viewpager.offscreenPageLimit = 3

当我用另一个片段替换片段A时,我在onDestroyView方法中设置viewPager=nullviewPagerAdapter=null,因此viewpager必须被垃圾回收。所以当我回到片段A时,为什么在将任何项添加到viewpager之前就调用了viewpager中片段的onCreateView方法?! - Soheil

1
在您的onCreateView方法中尝试这个:

if(view ==null)
{
       //your oncreate view code
 }

你的意思是将片段的视图保存在一个变量中,然后恢复它吗?显然,保存视图会消耗大量内存,而且没有意义。 - Soheil

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