Search code examples
androidandroid-tabsandroid-design-library

Design Library TabLayout, tab indicator bouncing after scroll


EDIT The latest design libraries fixed this issue

compile 'com.android.support:design:+'


I am working with the TabLayout in two instances, PagerAdapter and FragmentStatePagerAdapter. In both cases the tab indicator bounces, when swiped between pages. The tab indicator doesn't bounce when clicking tab's to change pages.

I am not sure if it is an error on my part, it is a known issue, or part of the guidelines. If you need more code, or the other example I will post it.

FragmentStatePagerAdapter

    mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int position) {
            LogMeal log = mLogMealAdapter.getItem(position);
            return MealViewFragment.newInstance(log.getId());
        }

        @Override
        public CharSequence getPageTitle(int position) { // Tab text
            LogMeal logMeal1 = mLogMealAdapter.getItem(position);
            String s;
            if (logMeal1.getMealName().toString().trim().length() > 12) {
                s = logMeal1.getMealName().substring(0, 12) + "..";
            } else {
                s = logMeal1.getMealName();
            }
            return s;
        }

        @Override
        public int getCount() {
            return mLogMealAdapter.getCount();
        }
    });

    tabs.setTabTextColors(Color.parseColor("#80ffffff"), Color.parseColor("#ffffff"));
    if (mLogMealAdapter.getCount() == 1) {
        tabs.setTabMode(TabLayout.MODE_FIXED);
    } else {
        tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
    }
    tabs.setupWithViewPager(mViewPager);
    mViewPager.setCurrentItem(position);

XML

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar_meal_view"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@color/primary"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_below="@+id/toolbar_meal_view"
        android:background="@color/primary"
        android:theme="@style/ToolbarTheme"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tabs"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:layout_below="@+id/tabs"
        android:background="@drawable/toolbar_shadow"/>

</RelativeLayout>

Solution

  • I had a similar problem recently.
    My workaround:

    1) Change tabs.setupWithViewPager(mViewPager); for

        \\ use own OnPageChangeListener 
        mViewPager.addOnPageChangeListener(new MyPageScrollListener(mTabLayout));  
    
        \\ Manually add tabs, for example:  
        mTabLayout.addTab(mTabLayout.newTab().setText(mViewPager.getAdapter().getPageTitle(0)));
        mTabLayout.addTab(mTabLayout.newTab().setText(mViewPager.getAdapter().getPageTitle(1)));  
    
        \\ use own OnTabSelectedListener  
        mTabLayout.setOnTabSelectedListener(new MyOnTabSelectedListener());  
    

    2) Add implementation for custom listeners

     private class MyPageScrollListener implements ViewPager.OnPageChangeListener {
        private TabLayout mTabLayout;
    
        public MyPageScrollListener(TabLayout tabLayout) {
            this.mTabLayout = tabLayout;
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
        }
    
        @Override
        public void onPageSelected(int position) {
            if(mTabLayout != null) {
                mTabLayout.getTabAt(position).select();
            }
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
    }
    
    private class MyOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            int position = tab.getPosition();
            if (mViewPager.getCurrentItem() != position) {
                mViewPager.setCurrentItem(position, true);
            }
        }
    
        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
    
        }
    
        @Override
        public void onTabReselected(TabLayout.Tab tab) {
    
        }
    }
    

    I hope it helps.