Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

android - ViewPager and RecyclerView issue with fragment transition

The setup is like so:

  • Single activity app (MainActivity) with nav_graph

  • HomeFragment has viewPager2 with 3 subfragments

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

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.

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()

Here's the adapter:

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


}

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()
    }

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It appears by trying out whole lot of different similar implementation so far I wasn't able to reproduce the issue after changing the "parentFragmentManager" into: activity?.supportFragmentManager


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...