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:
and that's what it's supposed to show:
this is the layout 0:
any ideas about this behaviour and how can i avoid it?
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.