Android 带有片段转换的ViewPager和RecyclerView问题

Android 带有片段转换的ViewPager和RecyclerView问题,android,android-jetpack,fragmentmanager,android-viewpager2,Android,Android Jetpack,Fragmentmanager,Android Viewpager2,设置如下所示: 带有导航图的单一活动应用程序(MainActivity) HomeFragment具有带有3个子片段的viewPager2 这3个片段中的每一个都是相同的片段,RecyclerView显示了不同的帖子列表 用户可以点击一篇文章,然后导航到全新的屏幕/片段(详细信息) 单击“后退”按钮会引发异常: java.lang.IllegalStateException:FragmentManager已在执行事务 位于androidx.fragment.app.FragmentMa

设置如下所示:

  • 带有导航图的单一活动应用程序(MainActivity)

  • HomeFragment具有带有3个子片段的viewPager2

  • 这3个片段中的每一个都是相同的片段,RecyclerView显示了不同的帖子列表

  • 用户可以点击一篇文章,然后导航到全新的屏幕/片段(详细信息)

  • 单击“后退”按钮会引发异常:

    java.lang.IllegalStateException:FragmentManager已在执行事务 位于androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1790) 位于androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1826) 位于androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297) 在androidx.viewpager2.adapter.FragmentStateAdapter$FragmentMaxLifecycleEnforcer.updateFragme

所以我的感觉是,问题发生在带有RecyclerView的ViewPager2和通过导航进行的片段转换之间。为什么?嗯,单击“后退”箭头使事务进入“主”屏幕,但主屏幕上的viewpager也处理片段转换,这不知何故造成了问题

为了提供更多上下文,以下是tabs/viewpager的设置方式(在HomeFragment中):

下面是适配器:

class PagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {

private val fragments = listOf<Fragment>(
    MyListFragment.newInstance(Type.TOP),
    MyListFragment.newInstance(Type.POPULAR),
    MyListFragment.newInstance(Type.NEW)
)

override fun getItemCount(): Int {
    return fragments.size
}

override fun createFragment(position: Int): Fragment {
    return fragments[position]
}


}
通过在setTabs方法中将parentFragmentManager更改为childFragmentManager,类似的问题在某个地方得到了解决,但这会创建另一个问题,在“RecyclerView已经设置了layoutManager”的行中引发异常


如果没有提供足够的信息,请告诉我。

通过尝试大量不同的类似实现,到目前为止,在更改“parentFragmentManager”后,我无法重现该问题进入:activity?.supportFragmentManager

通过尝试大量不同的类似实现,到目前为止,在更改“parentFragmentManager”后,我无法重现该问题进入:activity?.supportFragmentManager

您使用了错误的
FragmentManager
-对于完全包含在另一个布局中的每个片段(例如
ViewPager2
托管片段),您必须使用
子FragmentManager
正确嵌套片段

viewPager.adapter = PagerAdapter(childFragmentManager, lifecycle)

这不仅是正确恢复您的状态所必需的(使用活动的
supportFragmentManager
无法做到这一点),而且是为了确保父片段首先经历其状态转换,然后子片段才经历其转换,从而修复“已在执行的事务”问题。

您使用了错误的
碎片管理器
-对于完全包含在另一个布局中的每个碎片(例如您的
ViewPager2
托管碎片),您必须使用
子碎片管理器
正确嵌套碎片

viewPager.adapter = PagerAdapter(childFragmentManager, lifecycle)

这不仅是正确恢复您的状态所必需的(使用活动的
supportFragmentManager
无法做到这一点),而且是为了确保父片段首先经历其状态转换,然后子片段才经历其转换,从而修复“已在执行的事务”问题。

谢谢您的回复。然而,在尝试了这种方法之后,我遇到了另一个问题,那就是:在从细节片段返回homefragment(使用所有viewpager+recycler视图)之后,我在设置recyclerview的布局管理器时遇到了一个异常(这里:
binding.recyclerview.layoutManager=layoutManager
)。出现以下错误:
LayoutManager androidx.recyclerview.widget。LinearLayoutManager@6f31cd1已连接到回收视图
。有什么想法吗?好吧,我尝试了另一件事,你告诉我它是否有意义:因为在我的homefragment中,我曾经将layoutmanager保留为强引用字段,每次调用CreateView时都将其删除并创建新的layout manager,从而解决了这个问题。这听起来合理吗?是的,每次移动到
onCreateView
,您都应该创建一个新的布局管理器。我收到了错误
LayoutManager androidx.recyclerview.widget。LinearLayoutManager@6f31cd1当我在kotlin中使用
lazy
委托时,已附加到RecyclerView
;避免使用它来实例化适配器。谢谢你的回复。然而,在尝试了这种方法之后,我遇到了另一个问题,那就是:在从细节片段返回homefragment(使用所有viewpager+recycler视图)之后,我在设置recyclerview的布局管理器时遇到了一个异常(这里:
binding.recyclerview.layoutManager=layoutManager
)。出现以下错误:
LayoutManager androidx.recyclerview.widget。LinearLayoutManager@6f31cd1已连接到回收视图
。有什么想法吗?好吧,我尝试了另一件事,你告诉我它是否有意义:因为在我的homefragment中,我曾经将layoutmanager保留为强引用字段,每次调用CreateView时都将其删除并创建新的layout manager,从而解决了这个问题。这听起来合理吗?是的,每次移动到
onCreateView
,您都应该创建一个新的布局管理器。我收到了错误
LayoutManager androidx.recyclerview.widget。LinearLayoutManager@6f31cd1当我在kotlin中使用
lazy
委托时,已附加到RecyclerView
;避免使用它来实例化适配器。
viewPager.adapter = PagerAdapter(childFragmentManager, lifecycle)