我在一个Fragment
里面有一个Viewpager2
(我们称之为HomeFragment
)。Viewpager
本身也包含Fragments
。当我导航离开HomeFragment
时,它的视图将被破坏,当我导航回来时,视图将被重新创建。现在我在onViewCreated()
期间在HomeFragment
中设置了Viewpager2
的适配器。因此,当我导航回HomeFragment
时,将重新创建适配器,这也将重新创建Viewpager2
中的所有Fragments
,并且当前项将重置为0。如果我尝试重用在第一次创建HomeFragment
时示例化的适配器,则会出现异常,由于FragmentStateAdapter
:
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
checkArgument(mFragmentMaxLifecycleEnforcer == null);
有没有人知道我如何才能防止在导航回来时重新创建所有内容?否则,这将是一个相当大的性能开销,并阻碍我的UX。
5条答案
按热度按时间7ivaypg91#
您可以将ViewPager的初始页面作为NavHostFragment,这些页面具有自己的后台堆栈,这将导致实现下面的gif
为每个选项卡创建一个NavHost片段,或者可以将其添加到通用的NavHost片段中
此片段的布局
为
ViewPager2
的每个页面创建一个导航图,对于上面所示的 Jmeter 板,我们需要nav_graph_dashboard。此页的图形为
让我们将这些NavHostFragments与FragmentStateAdapter合并,并实现默认情况下不工作的后退导航。
您还需要注意内存泄漏,因此如果您的
ViewPager2
本身位于Fragment
中,请使用viewLifecycleOwner而不是lifeycleOwner
。您可以在此t utorial link中查看其他示例和更多内容。
dgenwo3n2#
我试过设置
而在那之后,碎片的行为就变得正常了。
有关OffscreenPageLimit的详细信息,请单击此处
myss37ts3#
我花了一点时间来分析这个问题,我已经为任何需要了解这个问题的人诊断出了问题所在。我试图尽可能地保持我的解决方案的常规性。如果我们看看你的陈述:
因此,当我导航回HomeFragment时,将重新创建适配器,这也将重新创建Viewpager2中的所有Fragments,并且当前项重置为0。
让我们来设计一些定义:
HomeFragment
是ViewPager2
的主机,MainActivity
是正在运行的Activity,它托管HomeFragment
以及在其中创建的所有片段MyFragment
的示例进行分页,您甚至可以对多种类型的片段进行分页,但这超出了本示例的范围。PagerAdapter
是你的FragmentStateAdapter
,它是HomeFragment
的ViewPager2
的适配器。在本例中,
MyFragment
具有构造函数constructor(id : Int)
。那么,PagerAdapter
可能会如下所示:我们面临的问题是,每次重新创建
PagerAdapter
时,都会调用构造函数,而该构造函数,正如我们在上面看到的,会将ids
设置为空列表。我的第一个想法是,也许我可以将
fm
切换为MainActivity
。我没有导航出MainActivity
,所以我不知道为什么,但这个解决方案不起作用。相反,您需要做的是从
PagerAdapter
中提取数据。创建一个“viewModel”:然后,在
PagerAdapter
中进行以下调整:最后,在
HomeFragment
中,您将得到如下内容:7xllpg7q4#
我使用
FragmentActivity
而不是Fragment
作为适配器的构造函数的参数,并且它工作了。当导航回HomeFragment
时,适配器被重新创建,但是子片段没有被重新创建。上一页:
现在:
或
yi0zb3m45#
这是ViewPager2(或者实际上是RecyclerView)https://issuetracker.google.com/issues/151212195中的一个错误
返回时必须重用旧适配器(以避免片段重复),并在HomeFragment的onDestroyView()中调用viewPager。adapter = null
[更新日期:04.08.2022]很奇怪,我的答案是downvoted o_O。同样,您不必在onViewCreated中重新创建适配器,这是一个错误(不仅对于ViewPager,而且对于RecyclerView和其他使用适配器方法的人)。