ViewPager和RecyclerView问题与片段过渡 [英] ViewPager and RecyclerView issue with fragment transition

查看:201
本文介绍了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

所以我的感觉是通过导航在带有RecyclerView的ViewPager2与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.

要提供更多背景信息,这是设置tab/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)

这不仅是为了正确恢复状态(使用活动的 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天全站免登陆