TabLayout 删除不必要的滚动

TabLayout remove unnecessary scrolling

我遇到了 android TabLayout

的棘手问题
import android.support.design.widget.TabLayout;

当我 select 最前面的选项卡向左滚动,然后向右滚动选项卡,select 最前面的选项卡向右滚动时,TabLayout 首先再次显示左侧选项卡,然后滚动到selected 标签到右边。这是我的设置代码

    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;
            }
        }
    }

和布局

    <?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>

改变你的方法如下:

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);
    }

希望对你有所帮助。

实际上您正在处理滚动问题。是的。问题是,TabLayout 扩展了 Horizo​​ntalScrollView。 试试这样的东西。

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;
}

}

经过大量搜索,我了解到我需要另一个组件,它看起来像 TabLayout,但不是 TabLayout。所以我用 ViewPagerIndicator

它与 TabLayout 非常相似,尽管它缺少 TabLayout 中存在的炫酷选择动画和选定选项卡指示器动画。它也不会调整文本大小以适合标签,这很好,它也不会调整标签大小以适合文本,这很糟糕(尝试了我知道的所有样式参数 - 无法使文本换行)。

但它可以很好地选择标签,无需额外滚动。不幸的是,AndroidArsenal 不包含比那个更好的解决方案(至少我搜索时没有)。

你可以试试这个代码

    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) { }
    });

或者您也可以直接对最后一行执行此操作

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

您可以使用这个自定义 ViewPager,也许它能帮到您 :)

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);
    }
}

我觉得值得用TabLayoutMediator

它看起来像这样

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