Material design library系列——TabLayout

前言

今天給大家帶來Material design系列的第四篇文章,TabLayout的使用,首先說明一下,什么是TabLayout,這里引用一下源碼中對TabLayout的介紹

TabLayout provides a horizontal layout to display tabs.

意思很明確,TabLayout提供了一個水平的布局用來展示Tabs。
那么在開發中相信大家在開發中經常會看到這樣的ui



像這樣多個tab切換,其實就可以用TabLayout來實現。

使用

首先在你的布局文件中加入該控件



然后在代碼中找到控件,并給他設置幾個tab


做到這一步你就能看到這樣的效果(PS:剛出iPhone8,我也來蹭一波熱度)



是不是很簡單,你只需要做這么一點操作就能實現tab切換的效果。

結合ViewPager使用

當然,在開發中,我們一般都是結合ViewPager來使用達到切換的目的,那么怎么做呢?
首先在布局文件中加入ViewPager控件



然后在代碼中找到該控件


附上adapter代碼

private class DemoPager extends FragmentPagerAdapter {
        private final List<Fragment> fragments;
        private final List<String> titles;

        public DemoPager(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
            super(fm);
            this.fragments = fragments;
            this.titles = titles;
        }

        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return fragments == null ? 0 : fragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    }

做到這一步,我們就可以看到這樣的效果。

TabLayout屬性介紹

  • app:tabSelectedTextColor:改變選中字體的顏色
  • app:tabTextColor:改變未選中字體的顏色
  • app:tabIndicatorColor:改變指示器顏色
  • app:tabBackground:改變背景色
  • app:tabIndicatorHeight:改變指示器高度

這五個屬性我都使用了,這里給大家看看效果(前方高能,非戰斗人員請迅速撤離)


哈哈,這個配色雖然有點辣眼睛,不過這不是重點,效果實現了就好,畢竟我們是開發人員,不是UI對吧,o(∩_∩)o 哈哈。

  • 添加圖標

如果只是文字,可能會有點單調,我們可以加一個圖標在上面,就像這樣,調用getTabAt拿到對應的tab,然后調用setIcon方法即可

  • app:tabMode

這個屬性的作用就是修改TabLayout的屬性,有2個值,fixed和scrollable,默認是fixed,fixed就是固定的,scrollable就是可以滑動,舉個栗子,我先多加幾個標題

fixed屬性

scrollable
  • app:tabGravity:內容的顯示模式,center是居中,fill是填滿
  • app:tabMaxWidth:tab最大寬度
  • app:tabMinWidth:tab最小寬度
  • app:tabContentStart:tab的"margin"

TabLayout的監聽事件

修改指示器長度

相信用過tablayout的朋友都知道,我們并不能找到直接修改指示器寬度的方法,這里就需要大家自己做操作了,當然這里會給大家帶來一種方法

public void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
        Class<?> tabLayout = tabs.getClass();
        Field tabStrip = null;
        try {
            tabStrip = tabLayout.getDeclaredField("mTabStrip");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        tabStrip.setAccessible(true);
        LinearLayout llTab = null;
        try {
            llTab = (LinearLayout) tabStrip.get(tabs);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
        int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());

        for (int i = 0; i < llTab.getChildCount(); i++) {
            View child = llTab.getChildAt(i);
            child.setPadding(0, 0, 0, 0);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
            params.leftMargin = left;
            params.rightMargin = right;
            child.setLayoutParams(params);
            child.invalidate();
        }
    }

然后你只需要在拿到tablayout之后調用一下該方法就好,就像這樣


效果圖


添加分割線

這個需求并不多,但是如果碰到了,那就乖乖的做吧。。。

 //先拿到tablayout
 LinearLayout linearLayout = (LinearLayout) tabLayout.getChildAt(0);
     linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
        //傳入一張圖片,我這里就用shape代替了
        linearLayout.setDividerDrawable(ContextCompat.getDrawable(this,
                R.drawable.divider));
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/red"/>
    <size android:width="2dp"/>
</shape>
分割線效果

自定義視圖setCustomView

比如我們要實現tab有兩行文字的需求,如果文字大小都相同,我們直接用\n換行就可以實現,就像這樣


如果上面textView字體大小與下面不同,或者一些奇奇怪怪的需求,那么就需要用到setCustomView了。
先給大家看一下效果圖


這樣的效果你用單純的\n肯定是實現不了的對吧。
這里給大家貼一下上述需求實現的代碼,大家可以做一個參考應用到自己的項目里面

        //先把你要的標題放到集合中
        List<String> topTitles = new ArrayList<>();
        topTitles.add("java");
        topTitles.add("php");
        topTitles.add("python");
        List<String> bottomTitles = new ArrayList<>();
        bottomTitles.add("c語言");
        bottomTitles.add("c++");
        bottomTitles.add(".net");

        //其次添加幾個tab
        tabLayout.addTab(tabLayout.newTab());
        tabLayout.addTab(tabLayout.newTab());
        tabLayout.addTab(tabLayout.newTab());

        //通過getTabCount方法拿到tab的數量
        int tabCount = tabLayout.getTabCount();

        for (int i = 0; i < tabCount; i++) {
            View view = View.inflate(this, R.layout.custom_view, null);
            ((TextView) view.findViewById(R.id.tv_top)).setText(topTitles.get(i));
            ((TextView) view.findViewById(R.id.tv_bottom)).setText(bottomTitles.get(i));
            //調用setCustomView方法設置自定義布局
            tabLayout.getTabAt(i).setCustomView(view);
        }

自定義布局文件我就不貼了,就是兩個TextView而已。

這里要注意了,當你這樣做了之后,app:tabSelectedTextColor和app:tabTextColor屬性就失效了,我們需要手動解決這個問題,給tablayout設置一個監聽

手動設置之后,確實能實現顏色切換的效果,但是這里還有一個問題,不知道大家發現沒有,那就是你必須挨個點擊之后,顏色改變才能生效,那么怎么辦呢,這里剛開始想到的是調用

mTabLayout.getTabAt(0).select();

手動選擇第一個tab,但是發現這樣并不能達到效果,所以最終的解決方案是這樣的


拿到listener對象,手動調用里面的方法,這樣效果就能實現了


總結

好了,TabLayout的使用到此結束了,祝大家工作順心,看到這里了你還不點贊,你的良心不會痛么(┬_┬)

以上純屬于個人平時工作和學習的一些總結分享,如果有什么錯誤歡迎隨時指出,大家可以討論一起進步。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容