自适应 Tab 宽度可以滑动文字逐渐变色的 TabLayout(仿今日头条顶部导航)

Posted Mr.Ding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自适应 Tab 宽度可以滑动文字逐渐变色的 TabLayout(仿今日头条顶部导航)相关的知识,希望对你有一定的参考价值。

 

TabLayout相信大家都用过,2015年Google大会上发布了新的android Support Design库里面包含了很多新的控件,其中就包含TabLayout,它可以配合ViewPager完成很好的效果。

一种类似于今日头条指示器,根据ViewPager的页面滑动,文字逐渐变色。

今日头条的顶部tab导航效果的实现,我们一般会用RadioGroup+Fragment+ViewPager来实现,适配器繁多,代码量大,今天我们来介绍TabLayout的使用。TabLayout为Android的Design库中的一个控件。首先我们来看一下运行的效果图:

 

ColorTrackTabLayout

先看下效果

使用

因为是继承TabLayout,所以用法跟TabLayout一模一样

 //隐藏Indicator
        mTab.setSelectedTabIndicatorHeight(0);
        //设置左右内边距
        mTab.setTabPaddingLeftAndRight(10,10);
        mTab.setupWithViewPager(mViewPager);

 

原理

ColorTrackLayout主要是继承了TabLayout,对它做了一些扩展。

既然是随着页面的滑动文字颜色渐变那么肯定少不了ViewPager的页面监听,这个在我们调用setupWithViewPager的时候TabLayout就已经添加监听。

 private void setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh,
            boolean implicitSetup) {
        ....

        if (viewPager != null) {
            mViewPager = viewPager;

            // Add our custom OnPageChangeListener to the ViewPager
            if (mPageChangeListener == null) {
                //添加了滑动监听
                mPageChangeListener = new TabLayoutOnPageChangeListener(this);
            }
            mPageChangeListener.reset();
            viewPager.addOnPageChangeListener(mPageChangeListener);

            // Now we\'ll add a tab selected listener to set ViewPager\'s current item
            mCurrentVpSelectedListener = new ViewPagerOnTabSelectedListener(viewPager);
            addOnTabSelectedListener(mCurrentVpSelectedListener);

            final PagerAdapter adapter = viewPager.getAdapter();
            if (adapter != null) {
                // Now we\'ll populate ourselves from the pager adapter, adding an observer if
                // autoRefresh is enabled
                setPagerAdapter(adapter, autoRefresh);
            }

            // Add a listener so that we\'re notified of any adapter changes
            if (mAdapterChangeListener == null) {
                mAdapterChangeListener = new AdapterChangeListener();
            }
            mAdapterChangeListener.setAutoRefresh(autoRefresh);
            viewPager.addOnAdapterChangeListener(mAdapterChangeListener);

            // Now update the scroll position to match the ViewPager\'s current item
            setScrollPosition(viewPager.getCurrentItem(), 0f, true);
        } else {
            // We\'ve been given a null ViewPager so we need to clear out the internal state,
            // listeners and observers
            mViewPager = null;
            setPagerAdapter(null, false);
        }
        ....

    }

 

创建了mPageChangeListener并添加了监听

所以我们必须要重写setupWithViewPager删除掉原来的监听,换成我们自己的监听

mPageChangeListener = new TabLayoutOnPageChangeListener(this);

    @Override
    public void setupWithViewPager(@Nullable ViewPager viewPager, boolean autoRefresh) {
        super.setupWithViewPager(viewPager, autoRefresh);
        try {
            //通过反射找到mPageChangeListener
            Field field = TabLayout.class.getDeclaredField("mPageChangeListener");
            field.setAccessible(true);
            TabLayoutOnPageChangeListener listener = (TabLayoutOnPageChangeListener) field.get(this);
            if (listener != null) {
                //删除自带监听
                viewPager.removeOnPageChangeListener(listener);
                mPageChangeListenter = new ColorTrackTabLayoutOnPageChangeListener(this);
                mPageChangeListenter.reset();
                viewPager.addOnPageChangeListener(mPageChangeListenter);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

 

 

还需要做的一点就是把TabLayout每一个的Tab布局替换成我们的。怎么替换呢?重写addTab,在添加的时候改成我们的布局

 @Override
    public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
        ColorTrackView colorTrackView = new ColorTrackView(getContext());
        colorTrackView.setProgress(setSelected ? 1 : 0);
        colorTrackView.setText(tab.getText() + "");
        colorTrackView.setTextSize(mTabTextSize);
        colorTrackView.setTag(position);
        colorTrackView.setTextChangeColor(mTabSelectedTextColor);
        colorTrackView.setTextOriginColor(mTabTextColor);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        colorTrackView.setLayoutParams(layoutParams);
        tab.setCustomView(colorTrackView);

        super.addTab(tab, position, setSelected);
        if (position == 0) {
            //默认选中第一个
            setSelectedView(position);
        }

        setTabWidth(position, colorTrackView);
    }

 借鉴: www.weyye.me/detail/colo…

其关键就是将我们的布局利用setCustomView方法来设置上去。

源码链接 https://github.com/DingXianSen/DcColorTabLayout

以上是关于自适应 Tab 宽度可以滑动文字逐渐变色的 TabLayout(仿今日头条顶部导航)的主要内容,如果未能解决你的问题,请参考以下文章

基于vue与vux做的可滑动tab组件

JavaScript提高:003:easy UI实现tab页面自适应问题

实现tab左右滑动切换与下拉刷新,上拉加载结合

原生TabLayout下标宽度不能自适应的解决方案

Android (基础自定义组件)viewpagertap滑动器

echarts的自适应问题(窗口自适应,侧边栏自适应,el-tab中的自适应)