3

This reported bug is causing me problems; https://issuetracker.google.com/issues/183847283

When combined with FragmentStateAdapter, ViewPager2.setCurrentItem doesn't always work. The TabLayout correctly changes (if you have one), but the ViewPager2 itself doesn't show the correct page.

Has anyone found a workaround?

2 Answers2

5

I had a similar problem, if not the same. The solution was to change fragments/tabs/pages in a specific order.

  1. The FragmentStateAdapter should be notified first of the change to the fragment.
  2. The TabLayout should then call selectTab under a post
  3. The ViewPager should then call setCurrentItem under a post, inside the TabLayouts post to selectTab.

This may be overkill but it worked for me.

Example

//or some other notify depending on your use case.
fragmentStateAdapter.notifyItemInserted(position);

tabLayout.post(()->{
     tabLayout.selectTab(tabLayout.getTabAt(position));
     viewPager2.post(()->{
          viewPager2.setCurrentItem(position);
          //I noticed on older devices like API 19
          //the viewPager wouldn't complete transformations
          //so we call this.
          viewPager2.requestTransform();
     });
});
avalerio
  • 2,072
  • 1
  • 12
  • 11
  • In my experience, the `tabLayout` does not manually need to be updated, as it's already mediated in ViewPager2 via the `TabLayoutMediator`. Also, I think you can do away with the "nested" post. For me this simple code fixed the bug fully: `viewPager2.post { viewPager2.setCurrentItem(position)}` – avalancha Jul 20 '22 at 14:31
  • 1
    The system I was working with could change tabs programmatically, for example tabs could be added, removed, and navigated to, without interacting with the tab layout itself. The `TabLayoutMediator` is only automatically called when the user actually uses the tab layout, with this solution you could programmatically change the tab and `tabLayout.selectTab(tabLayout.getTabAt(position));` will provoke the mediator. – avalerio Jul 20 '22 at 14:47
  • Sadly this doesn't work for me. The only work-around that worked for me is to delay the call to ViewPager2.setCurrentItem() for 1000ms. 1000ms is an arbitrary value and may not even work if the device is very slow. – rainai Nov 06 '22 at 17:41
  • 2
    What worked for me is to disable smooth scrolling `ViewPager2.setCurrentItem(position, false)`. Refer to my comment in the issue tracker here: https://issuetracker.google.com/issues/183847283#comment8 – rainai Nov 07 '22 at 03:38
0

I solved it like this:

viewPager.setCurrentItem(tab.getPosition());
                if (tab.getPosition()==0||tab.getPosition()==1||tab.getPosition()==2||tab.getPosition()==3){
                    pagerAdapter.notifyDataSetChanged();
                }
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
Mohit Der
  • 11
  • 2
  • Sadly, same issue. TabLayout correctly changes, but ViewPager2 doesn't. – brisdeveloper Jan 17 '22 at 03:52
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 17 '22 at 07:38