记一次TabLayout的用法

时间:2022-01-28 04:10:05

问题1:

最近在Android8.0上面遇到一个奇葩的事情,就是在布局文件里面设置TabLayout的item,不知为啥,运行起来的时候字体颜色没有显示,以下是没有显示的写法:

    <android.support.design.widget.TabLayout
        android:id="@+id/fragment_transaction_tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabIndicatorHeight="@dimen/space_6"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextAppearance="@style/TabLayoutTextStyle"
        app:tabTextColor="@color/gray_A4A4A4" >

        <android.support.design.widget.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="@string/recharge_other" />

        <android.support.design.widget.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="@string/recharge_buy" />
    </android.support.design.widget.TabLayout>

先不深究,现在说解决办法:直接在代码里面设置就可以了

vTabLayout.addTab(vTabLayout.newTab().setText(getString(R.string.fragment_transaction_self)));

问题2:

Indicator宽度受tabItem的宽度牵制,总感觉Indicator太长不好看,现在要设置自己满意的宽度。

进入TabLayout分析了一下代码,发现里面的tabItem都是添加进SlidingTabStrip这个控件的,其继承LinearLayout

既然是继承LinearLayout这样就好办了,现在的打算是控制tabItem的Margin

做法是:利用反射从TabLayout里面拿到SlidingTabStrip,在从里面获取tabItem

 /**
     * 通过反射获取SlidingTabStrip设置tabItem宽
     *
     * @param tabs
     * @param leftMargin
     * @param rightMargin
     */
    public void setIndicator(TabLayout tabs, int leftMargin, int rightMargin) {
        Class<?> tabLayout = tabs.getClass();
        Field tabStrip = null;
        try {
            tabStrip = tabLayout.getDeclaredField("mTabStrip");
        } catch (NoSuchFieldException e) {
            LogUtils.d("not found!");
        }
        tabStrip.setAccessible(true);
        LinearLayout llTab = null;
        try {
            llTab = (LinearLayout) tabStrip.get(tabs);
        } catch (IllegalAccessException e) {
           LogUtils.d("IllegalAccessException!");
        }
        int left = getResources().getDimensionPixelOffset(leftMargin);
        int right = getResources().getDimensionPixelOffset(rightMargin);
        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();
        }
    }

具体用法:

在布局加载完之后执行下面方法

 vTabLayout.post(new Runnable() {
            @Override
            public void run() {
                setIndicator(vTabLayout, R.dimen.space_80, R.dimen.space_80);
            }
        });


问题3:

一个不熟悉的用法,现在终于长见识了,TabLayout有这么一段代码

 mTabTextAppearance = a.getResourceId(R.styleable.TabLayout_tabTextAppearance,
                R.style.TextAppearance_Design_Tab);

        // Text colors/sizes come from the text appearance first
        final TypedArray ta = context.obtainStyledAttributes(mTabTextAppearance,
                android.support.v7.appcompat.R.styleable.TextAppearance);
        try {
            mTabTextSize = ta.getDimensionPixelSize(
                    android.support.v7.appcompat.R.styleable.TextAppearance_android_textSize, 0);
            mTabTextColors = ta.getColorStateList(
                    android.support.v7.appcompat.R.styleable.TextAppearance_android_textColor);
        } finally {
            ta.recycle();
        }

刚开始时一直没有留意ta是关联到mTabTextAppearance的,就以为直接在布局里面用系统属性就能设置字体大小,后来运行了一下发现没有效果,立马去看了一下代码,尴尬,原来是需要通过tabTextAppearance这个属性调用样式才能用到系统的属性

 <android.support.design.widget.TabLayout
        android:id="@+id/fragment_transaction_tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabIndicatorHeight="@dimen/space_6"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextAppearance="@style/TabLayoutTextStyle"
        app:tabTextColor="@color/gray_A4A4A4" />
<style name="TabLayoutTextStyle">
        <item name="android:textSize">@dimen/font_size_28px</item>
    </style>