2

I have basic ViewPager2 with Tablayout - and in each page I have different fragments. When I need to open this view NOT from first (default) tab I'm doing smth like this:

 viewPager.currentItem = selectedTabPosition

This code select tab, but inside it is opening fragment from first tab! Only when I'm selecting the tabs by tapping on it - I can see the right fragment in each tabs. I've also try to select with Tablayout like this:

tabLayout.getTabAt(position)?.select()

But this code doesn't help and also work with this bug. Also I've try to set viewPager.currentItem with post / postDelay - but this doesn't work too.

Maybe I've lost something? Or it is a bug in ViewPager2 ?

(EDIT - ViewPager code)

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    setupPagerAdapter()
}

private fun setupPagerAdapter() {
    val adapter = MainDocumentScreenPagerAdapter(this)

    binding?.viewPager?.letUnit {
        it.adapter = adapter
        binding?.tabsPagerView?.attachViewPager(requireContext(), it, adapter)

        // set tab
        it.currentItem = params.pageType.ordinal
}

Adapter code

class MainDocumentScreenPagerAdapter (fragment: Fragment) : ViewPager2TitleAdapter(fragment) {

override fun getItemCount(): Int = DocumentPageType.values().size

override fun createFragment(position: Int): Fragment {
    val pageType = DocumentPageType.values().firstOrNull { it.ordinal == position } ?: throw IllegalStateException()

    val params = DocumentListFragment.createParams(pageType)
    return DocumentListFragment.newInstance(params)
}

override fun getPageTitle(position: Int): Int? {
    return when (position) {
        DocumentPageType.ALL.ordinal -> DocumentPageType.ALL.title
        DocumentPageType.SIGN.ordinal -> DocumentPageType.SIGN.title
        DocumentPageType.ACCEPT.ordinal -> DocumentPageType.ACCEPT.title
        DocumentPageType.CONFIRM.ordinal -> DocumentPageType.CONFIRM.title
        DocumentPageType.REJECT.ordinal -> DocumentPageType.REJECT.title
        else -> null
    }
}

Where ViewPager2TitleAdapter is :

abstract class ViewPager2TitleAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
abstract fun getPageTitle(position: Int): Int?

DocumentListFragment inside it create view, based on param object.

I've also try to create adapter inside OnCreate - but it doesn't affect this case.


The last, but not least - when I've try to open tab, which is out from screen (I've scrollable tabs) - viewPager open selected tab with correct fragment on it.. So, the problem occurs only when I've try to open first 4 tabs (look at the image), which is showing on screen. Bit starting from 5 and next tabs - has selected correct.

enter image description here

alena_fox_spb
  • 697
  • 1
  • 8
  • 24

2 Answers2

6

So, the decision is in this line of code:

it.setCurrentItem(params.pageType.ordinal, false)

but I was doing it like this:

it.currentItem = params.pageType.ordinal

boolean false make magic in this case - It disable smooth scroll. I've got it from this answer about ViewPager2:

https://stackoverflow.com/a/67319847/4809482

alena_fox_spb
  • 697
  • 1
  • 8
  • 24
1

I think an easier more reliable fix is to defer to next run cycle instead of unsecure delay e.g

viewPager.post {
   viewPager.setCurrentItem(1, true)
}
Ankit Gupta
  • 512
  • 1
  • 6
  • 19