Search code examples
androidandroiddesignsupportandroid-tablayout

TabLayout v23 doesn't scroll with ViewPager scroll


With the new design support library 23.0.0, the tabs for TabLayout are not being scrolled at the time you drag the ViewPager asociated. The tabs are only scrolled when you finish the dragging and click up (when the tab is already selected). This was working fine on 22.2.1

Do I have to add something more to get it work like in 22.2.1? Is it a bug? Is there a workaround?

EDIT

Bug fixed with the last version 23.0.1


Solution

  • Here is a workaround that solves it, proposed by Chris Banes (The main developer of the design support library). This issue was mentioned on the Google Issues page here, and solved here.

    Put this code when setting the ViewPager:

        viewPager.clearOnPageChangeListeners();
        viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));
    

    Also add this class:

    private static class TabLayoutOnPageChangeListener implements ViewPager.OnPageChangeListener {
    
        private final WeakReference<TabLayout> mTabLayoutRef;
        private int mPreviousScrollState;
        private int mScrollState;
    
        public TabLayoutOnPageChangeListener(TabLayout tabLayout) {
            mTabLayoutRef = new WeakReference<>(tabLayout);
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
            mPreviousScrollState = mScrollState;
            mScrollState = state;
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            final TabLayout tabLayout = mTabLayoutRef.get();
            if (tabLayout != null) {
                final boolean updateText = (mScrollState == ViewPager.SCROLL_STATE_DRAGGING)
                        || (mScrollState == ViewPager.SCROLL_STATE_SETTLING
                        && mPreviousScrollState == ViewPager.SCROLL_STATE_DRAGGING);
                tabLayout.setScrollPosition(position, positionOffset, updateText);
            }
        }
    
        @Override
        public void onPageSelected(int position) {
            final TabLayout tabLayout = mTabLayoutRef.get();
            if (tabLayout != null) {
                tabLayout.getTabAt(position).select();
            }
        }
    }