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); }
其關鍵就是將我們的布局利用setCustomView方法來設置上去。
