RexSplode
RexSplode

Reputation: 1505

TabLayout remove unnecessary scrolling

I've encountered the tricky problem with android TabLayout

import android.support.design.widget.TabLayout;

To see what's going on, look at this gif

When I select the foremost tab to the left, then scroll tabs to the right and select the foremost tab to the right, TabLayout first shows me the left tab again and then scrolls to selected tab to the right. Here's my setup code

    void setupTabs(ViewPager viewPager, TabLayout tabLayout) {
       ProductsPagerAdapter adapter = new ProductsPagerAdapter(getChildFragmentManager(), rootCategory.getChildCategories());
       viewPager.setAdapter(adapter);
       tabLayout.setupWithViewPager(viewPager);

       setStartingSelection(viewPager, adapter);


   }

    private void setStartingSelection(ViewPager viewPager, ProductsPagerAdapter adapter) {
        for(int i = 0 ; i < adapter.getCount(); i++){
            String title = (String) adapter.getPageTitle(i);
            if(title.equals(selectedCategory.getName())){
                viewPager.setCurrentItem(i);
                break;
            }
        }
    }

And layout

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/toolbar_color"
            app:navigationIcon="@drawable/ic_back_white"
            app:title="@string/title_transport"
            app:titleTextColor="@color/title_color"/>


        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="scrollable"
            app:tabTextColor="@color/white"
            app:tabIndicatorColor="@color/tab_indicator"
            app:tabGravity="fill"/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:background="@android:color/white" />

</LinearLayout>

Upvotes: 10

Views: 7013

Answers (7)

ryan kun
ryan kun

Reputation: 1

try to wrap tablayout in horizontal scoll view like this

        <HorizontalScrollView
            android:id="@+id/horizontal_scroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/VW_C1">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/RankList"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@color/white"
                app:tabIndicator="@color/white"
                app:tabMode="scrollable" />

        </HorizontalScrollView>

Upvotes: 0

I think it's worth using TabLayoutMediator

and it will look like this

TabLayoutMediator(tabs, view_pager, true, false) { tab, position ->
        tab.text = ""
}.attach()

Upvotes: 1

jame
jame

Reputation: 1

You can use this custom ViewPager, may be it can help you :)

public class NonSmoothViewPager extends ViewPager {

    private boolean mIsEnabledSwipe = true;

    public NonSmoothViewPager(Context context) {
        super(context);
    }

    public NonSmoothViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setEnabledSwipe(boolean isEnabledSwipe) {
        mIsEnabledSwipe = isEnabledSwipe;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mIsEnabledSwipe && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return mIsEnabledSwipe && super.onInterceptTouchEvent(event);

    }

    @Override
    public void setCurrentItem(int item) {
        super.setCurrentItem(item, false);
    }

    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        super.setCurrentItem(item, false);
    }
}

Upvotes: 0

IvanP
IvanP

Reputation: 1104

you can try this code

    tabLayout.setupWithViewPager(viewPager);
    // little hack to prevent unnecessary tab scrolling
    tabLayout.clearOnTabSelectedListeners();
    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition(), false);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) { }

        @Override
        public void onTabReselected(TabLayout.Tab tab) { }
    });

or you can also do this directly for the last line

tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition(), false);
    }
});

Upvotes: 5

RexSplode
RexSplode

Reputation: 1505

After a lot of search I understood that I need another component which will look like TabLayout, but won't be TabLayout. So I used ViewPagerIndicator.

It is very similar to TabLayout, though it lacks cool selection animations and selected tab indicator animations, which are present in TabLayout. It also doesn't resize text to fit tabs, which is good, and it doesn't resize tabs to fit text either, which is bad (tried all style parameters that I know - could not make it wrap the text).

But it selects tabs just fine and without additional scrolling. AndroidArsenal unfortunately does not contain solutions, which are better than that (at least it didn't when I searched).

Upvotes: 0

Noorul
Noorul

Reputation: 3444

Actually you are dealing with Scrolling issue. Yes. the thing is, TabLayout Extends HorizontalScrollView. try Something like this.

public class CustomTabLayout extends TabLayout {

public CustomTabLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

public CustomTabLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public CustomTabLayout(Context context) {
    super(context);
    init(context);
}

void init(Context ctx){

}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Do not allow touch events.
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    // Do not allow touch events.
    return false;
}

}

Upvotes: 4

Amrut Bidri
Amrut Bidri

Reputation: 6360

Change your method as below:

private void setStartingSelection(ViewPager viewPager, ProductsPagerAdapter adapter) {
        int tabPosition=0;
        for(int i = 0 ; i < adapter.getCount(); i++){
            String title = (String) adapter.getPageTitle(i);
            if(title.equals(selectedCategory.getName())){
                tabPosition=i;
                break;
            }
        }
        viewPager.setCurrentItem(tabPosition);
    }

I hope this helps you.

Upvotes: 0

Related Questions