【问题标题】:ViewPager and RecyclerView issue with fragment transition片段转换的 ViewPager 和 RecyclerView 问题
【发布时间】:2021-03-04 20:36:57
【问题描述】:

设置是这样的:

  • 带有 nav_graph 的单个活动应用 (MainActivity)

  • HomeFragment 有 viewPager2 和 3 个子片段

  • 这 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

所以我的感觉是问题发生在 ViewPager2 与 RecyclerView 和 FragmentTransitions 通过导航之间。为什么?好吧,单击“返回”箭头会使事务转到“主”屏幕,但具有 viewpager 的主屏幕也会处理片段转换,这会以某种方式产生问题。

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

    val viewPager: ViewPager2 = container.findViewById(R.id.viewPager)
    viewPager.adapter = PagerAdapter(parentFragmentManager, lifecycle)

    val tabLayout: TabLayout = container.findViewById(R.id.tabLayout)
    val names = arrayOf("Najbolje", "Popularno", "Novo")

    TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = names[position] }.attach()

这是适配器:

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]
}


}

这里是设置recyclerview的代码:

private fun setupRecyclerView() {
        val adapter = MyListAdapter(requireContext(), myService)

        binding.recyclerView.adapter = adapter
        binding.recyclerView.layoutManager = layoutManager

        viewModel.posts.observe(viewLifecycleOwner) { post -> adapter.submitList(posts.map { PostItem(it) }) }

        addScrollListener()
    }

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

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

【问题讨论】:

    标签: android android-jetpack fragmentmanager android-viewpager2


    【解决方案1】:

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

    viewPager.adapter = PagerAdapter(childFragmentManager, lifecycle)
    

    这不仅需要正确恢复您的状态(使用活动的supportFragmentManager 不会做的事情),而且要确保父片段首先经历其状态转换,然后子片段才会经历他们的状态转换转换,修复“已经在执行的事务”问题。

    【讨论】:

    • 感谢您的回复。然而,在尝试了这种方法之后,我遇到了另一个问题,那就是:从详细信息片段返回到 homefragment(包含所有 viewpager+recycler 视图)后,我在设置 recyclerview 的布局管理器时遇到异常(这里: binding.recyclerView.layoutManager = layoutManager)。错误是:LayoutManager androidx.recyclerview.widget.LinearLayoutManager@6f31cd1 is already attached to a RecyclerView。有什么想法吗?
    • 好吧,我尝试了另一件事,你告诉我这是否有意义:因为在我的 homefragment 中,我曾经将 layoutmanager 作为一个强大的参考。字段,通过删除它并在每次调用 onCreateView 时创建新的布局管理器来解决问题。这听起来合理吗?
    • 是的,每次移至onCreateView 时都应该创建一个新的布局管理器。
    • 我在 kotlin 中使用 lazy 委托时收到错误 LayoutManager androidx.recyclerview.widget.LinearLayoutManager@6f31cd1 is already attached to a RecyclerView;避免使用它来实例化适配器。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多