片段转换的 ViewPager 和 RecyclerView 问题 [英] ViewPager and RecyclerView issue with fragment transition

查看:39
本文介绍了片段转换的 ViewPager 和 RecyclerView 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置如下:

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

  • Single activity app (MainActivity) with nav_graph

HomeFragment 有 viewPager2 和 3 个子片段

HomeFragment has viewPager2 with 3 subfragments

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

Each of these 3 fragments are same fragment with RecyclerView showing different list of posts

用户可以点击帖子并导航到全新的屏幕/片段(详细信息)

User can click on a post and that navigates to completely new screen/fragment (Details)

点击返回"按钮抛出异常:

Clicking "Back" button throws exception:

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

java.lang.IllegalStateException: FragmentManager is already executing transactions at androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1790) at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1826) at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297) at androidx.viewpager2.adapter.FragmentStateAdapter$FragmentMaxLifecycleEnforcer.updateFragme

所以我的感觉是问题发生在 ViewPager2 与 RecyclerView 和 FragmentTransitions 之间通过导航.为什么?好吧,点击返回"箭头使交易到主"屏幕,但主屏幕的 viewpager 也处理片段转换,这以某种方式产生了问题.

So my feeling is that issue happens between ViewPager2 with RecyclerView and FragmentTransitions through navigation. Why? Well, clicking "back" arrow makes the transaction to 'home' screen, but also home screen having viewpager also deals with fragment transitions and this somehow creates the issue.

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

To give more context, this is how tabs/viewpager is set (in 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 的代码:

and here's the code for setting up 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"的行中引发异常

One of the similar issues was somewhere solved by changing parentFragmentManager to childFragmentManager within setTabs method, but that creates another issue that throws exception among the lines of 'RecyclerView already has layoutManager set up'

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

Let me know if not enough information has been provided.

推荐答案

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

You're using the wrong FragmentManager - for every fragment that is fully contained within the layout of another (such as your ViewPager2 managed fragments), you must use childFragmentManager to properly nest the fragments.

viewPager.adapter = PagerAdapter(childFragmentManager, lifecycle)

这不仅是为了正确恢复您的状态(使用 Activity 的 supportFragmentManager 不会这样做),而且还需要确保父片段首先经历其状态转换,然后才执行子片段经历它们的转换,修复已经执行的事务";问题.

This is required not only to restore your state properly (something which using the activity's supportFragmentManager will not do), but to ensure that the parent fragment goes through its state transitions first and only then does the child fragments go through their transitions, fixing the "already executing transactions" issue.

这篇关于片段转换的 ViewPager 和 RecyclerView 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆