具有Viewpager2的键FragmentStateAdapter的片段不再存在

o4tp2gmn  于 2022-11-13  发布在  Android
关注(0)|答案(6)|浏览(294)

我 正在 为 我 的 项目 使用 ViewPager2 。 我 需要 使用 带有 ViewPager2 的 片段 内 的 嵌套 片段 。 它 工作 起来 很 有 魅力 , 直到 我 尝试 在 片段 之间 导航 ( 不 是 嵌套 的 片段 ) 。
第 一 次 在 片段 之间 导航 后 , 应用 程序 崩溃 , 并 出现 下面 解释 的 错误 。
包含 嵌套 片段 的 片段 OnCreateView 方法 :

View view = inflater.inflate(R.layout.orders_fragment, null);

ViewPager2 viewPager = view.findViewById(R.id.childViewPager);

TabLayout tabs = view.findViewById(R.id.tabs);

SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(),getLifecycle());

viewPager.setAdapter(sectionsPagerAdapter);

TabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy = (tab, position) -> {

    String[] order_activity_tabs = getResources().getStringArray(R.array.situations);

    for (int i=0; i<order_activity_tabs.length; i++) {

        if(i==position)
            tab.setText(order_activity_tabs[i]);

    }
};

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabs, viewPager, tabConfigurationStrategy);
tabLayoutMediator.attach();

return view;

中 的 每 一 个
当 我 返回 包含 嵌套 片段 的 片段 时 , 它 会 崩溃

java.lang.IllegalStateException: Fragment no longer exists for key f#0: unique id 4fbe17b8-5e22-4e07-a543-4a79445ad39c
        at androidx.fragment.app.FragmentManagerImpl.getFragment(FragmentManagerImpl.java:365)
        at androidx.viewpager2.adapter.FragmentStateAdapter.restoreState(FragmentStateAdapter.java:549)
        at androidx.viewpager2.widget.ViewPager2.restorePendingState(ViewPager2.java:350)
        at androidx.viewpager2.widget.ViewPager2.dispatchRestoreInstanceState(ViewPager2.java:375)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4045)
        at android.view.View.restoreHierarchyState(View.java:20253)
        at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:548)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:907)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)

格式
有 针对 FragmentStatePagerAdapter 的 解决 方案 , 但 没有 针对 FragmentStateAdapter 的 解决 方案 。 由于 我 无法 覆盖 FragmentStateAdapter 中 的 方法 , 因此 无法 实现 此 解决 方案 。
感谢 您 阅读 本文 。 任何 帮助 都 将 不胜 感激 。

trnvg8h3

trnvg8h31#

将viewpager2与FragmentStateAdapter一起使用时,其行为与FragmentStatePagerAdapter类似
实际上有两种方法可以解决这个问题
第一个方法是在viewpager2中将setSaveEnabled()设置为false

viewpager2.setSaveEnabled(false)

另一个是在我们的适配器上覆盖restoreState并返回null
检查:https://developer.android.com/reference/androidx/viewpager2/adapter/FragmentStateAdapter

重要事项

请注意,这不应该是禁用状态的推荐方式,这应该适用于某些用例,但对于生产应用程序,请考虑保存片段的状态或将状态从状态保持器(如viewmodel)重新发送到UI

cnwbcb6i

cnwbcb6i2#

您只需在布局文件中使用以下属性设置viewpager2

android:saveEnabled="true"
tcbh2hod

tcbh2hod3#

尝试在FragmentStateAdapter内的片段参数中调用requireActivity()

private inner class ScreenSlidePagerAdapter(fa: FavoriteFragment) : FragmentStateAdapter(fa.requireActivity())
3vpjnl9f

3vpjnl9f4#

viewpager2与recyclerview https://issuetracker.google.com/issues/154751401分离时出现问题
据我所知,有两种修复方法:
1.在xml viewpager2组件中添加此行。

android:saveEnabled="false"

但是上面的代码并没有恢复当前示例,每次popsBack时,fragment都会重新创建当前示例。
1.建议的解决方案是在您的片段上添加以下行

override fun onDestroyView() {
   super.onDestroyView()
   binding.pager.adapter = null
}
enxuqcxy

enxuqcxy5#

我的问题通过实现新的导航组件解决了。它本身处理片段转换。任何遇到这个问题的人都可以改变他们的导航方法。

b4qexyjb

b4qexyjb6#

我刚刚遇到了同样的问题。原因是当包含的片段被重新创建时,它的childFragmentManager也被重新创建了。FragmentStateAdapter在传递的fragmentManager中查找它恢复状态的片段。
我的解决方案是让它使用活动的fragmentManager而不是片段的fragmentManager,例如,使用接受如下活动的构造函数

class MyAdapter(f: Fragment) : FragmentStateAdapter(f.activity!!)

相关问题