Search code examples
androidandroid-fragmentsandroid-viewpager2

Android: ViewPager2 setting the starting page on creation not working


I have a viewpager containning two fragments, and a viewModel (stored in the parent activity) holding a record to the index of current page being visible.

here is the setUp of the parent fragment:

 override fun setUp() {
    super.setUp()
    titles = arrayOf(R.string.providers, R.string.create_provider)
    fragments = arrayOf(ProvidersListFragment(), CreateProviderFragment())
    pagerAdapter = BaseFragmentAdapter(this, fragments = fragments)
}

override fun setUpViews() {
    super.setUpViews()
    binding.page.adapter = pagerAdapter
    TabLayoutMediator(binding.tabs, binding.page) { tab, position ->
        tab.text = getString(titles[position])
    }.attach()
    binding.page.currentItem = viewModel.currentPage.value!!
}

override fun setUpObservers() {
    super.setUpObservers()
    viewModel.currentPage.observe(viewLifecycleOwner, {
        Log.d(TAG, "setUpObservers: it = $it")
        if (it != binding.page.currentItem)
            binding.page.currentItem = it
    })
}

the 3 methods above are called inside onResume().

the ViewModel holds the record to the current index like this: var currentPage = MutableLiveData<Int>().apply { value = 1 }

technically the starting page should be index 1, my case the TabMediator shows as if the page 1 is selected, but the layout is showing the content of page 0 (not even fully loaded).

that's what it's showing:

the error layout

and that's what it's supposed to show:

enter image description here

this is the layout 0:

enter image description here

any ideas about this behaviour and how can i avoid it?


Solution

  • I worked around this by creating a navigation action to take me directly to the desired page of the fragment. And since this is a workaround not a solution, it doesn't conform a 100% to my need, when i navigate to the fragment it's being created as a single fragment and not a page.

    I also did something else in a fragment that had the functionality of image picker. the issue was that when I'm on page 2 (creation fragment) and try to select an image, when I finish selecting, I'd find myself on the page 1. what I did was the following:

    On the fragment holding the pager:

        override fun setUpObservers() {
            // this method is called inside onResume()
        super.setUpObservers()
        if (binding.page.currentItem != viewModel.page)
            binding.page.currentItem = viewModel.page
        }
    

    on the other fragments:

        override fun onResume() {
        super.onResume()
        productsViewModel.page = 0 //the other fragment set this to 1
         }
    

    the viewmodel is created with the main activity's store:

    private val productsViewModel: ProductsViewModel by viewModels(this::requireActivity)
    

    hope this can help anyone with the same issue.