Tablayout設置下劃線長度的幾種方法以及遇到空指針問題。

方法一反射設置

利用反射獲取到tablayout的mTabStrip,進行設置:

很多人反饋原來的方法失效了,
sdk 28的Tablayout 的源碼發生了變化。修改如下:

public void setIndicatorWidth(@NonNull final TabLayout tabLayout, final int margin) {
        tabLayout.post(new Runnable() {
            @Override
            public void run() {
                try {
                    // 拿到tabLayout的slidingTabIndicator屬性
                    Field slidingTabIndicatorField = tabLayout.getClass().getDeclaredField("slidingTabIndicator");
                    slidingTabIndicatorField.setAccessible(true);
                    LinearLayout mTabStrip = (LinearLayout) slidingTabIndicatorField.get(tabLayout);
                    for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                        View tabView = mTabStrip.getChildAt(i);
                        //拿到tabView的mTextView屬性
                        Field textViewField = tabView.getClass().getDeclaredField("textView");
                        textViewField.setAccessible(true);
                        TextView mTextView = (TextView) textViewField.get(tabView);
                        tabView.setPadding(0, 0, 0, 0);
                        // 因爲想要的效果是字多寬線就多寬,所以測量mTextView的寬度
                        int width = mTextView.getWidth();
                        if (width == 0) {
                            mTextView.measure(0, 0);
                            width = mTextView.getMeasuredWidth();
                        }
                        // 設置tab左右間距,注意這裏不能使用Padding,因爲源碼中線的寬度是根據tabView的寬度來設置的
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
                        params.width = width;
                        params.leftMargin = margin;
                        params.rightMargin = margin;
                        tabView.setLayoutParams(params);
                        tabView.invalidate();
                    }
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
    }

28版本去除水波紋:

app:tabBackground="@null"
app:tabRippleColor="@null"

然而有些人會遇到空指針

tabStrip = tabLayout.getDeclaredField(&quot;mTabStrip&quot;);

這句代碼取不到值,這是因爲混淆的時候把tablayout給混淆了。

在混淆裏面加入這句即可。

-keep class android.support.design.widget.TabLayout{*;}

這種方法的問題是利用反射實現的,等sdk更新之後,這方法還可能失效。而且tablayout的下劃線長度不能太短,margin也影響到了tab標題的寬度,margin設置太大,文字都放不下了。

二,sdk 28+,直接設置文字下劃線等寬

在sdk>=28中,如果你的需求恰好是下劃線和文字等寬,那麼你可以最簡單輕鬆地實現這一功能。

在xml的tablayout標籤加上這一句代碼就完事了。

 app:tabIndicatorFullWidth="false"

**

三、自定義Indicator 樣式(推薦)

**

Indicator 是允許我們設置 drawable 來自定義樣式的,我們可以在透明的背景裏面包裹一個你需求寬度的shape,就可以實現這一功能,而且Indicator 的樣式更加豐富多樣。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">   
    <item android:gravity="center">     
      <shape>
            <size
                android:width="20dp"
                android:height="5dp" />

            <corners android:radius="5dp" />
            <solid android:color="@color/blue" />

        </shape>
    </item>

</layer-list>

然後xml的tablayout加入就好了

app:tabIndicator="@drawable/tab_indicator"

需要注意的是,你原來設置的如果有tabIndicatorcolor 屬性,你shape中的填充色不會生效,需要設置統一,或者去掉一個就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章