修改TabLayout的下劃線指示器長度

TabLayout用過的小伙伴都知道屋讶,在默認的情況下它的下劃線指示器長度是與你的標題長度對應(yīng)的,像下方圖示一樣:

為什么會這樣呢爆班?查看源碼你就會發(fā)現(xiàn):這個下劃線指示器的寬度使用的是 所有tabView中的最大寬度(循環(huán)讀取所有tabView矩乐,獲取最大寬度),而且TabLayout本身并沒有提供設(shè)置這個指示器寬度的方法傀蚌。而現(xiàn)在問題來了,如果需要修改這個寬度該怎么樣做呢?

接下來介紹兩種方法:

第一種:僅限于所有的tabView的text字數(shù)都是相同字數(shù)柳譬,比如所有的圖中所有的tab字數(shù)都是2個

直接上代碼喳张,具體解釋請看注釋

```

/**

* 通過反射機制 修改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();

? ? }

//設(shè)置模式

? ? tabStrip.setAccessible(true);

? ? //獲得tabview

? ? LinearLayout llTab =null;

? ? try {

llTab = (LinearLayout) tabStrip.get(tabs);

? ? }catch (IllegalAccessException e) {

? ? ?e.printStackTrace();

? ? }

//設(shè)置tabView的padding為0,并且設(shè)置了margin

? ? 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();

? ? }

}

```

然后使用的話,直接調(diào)用方法即可.必須要在Tablayout渲染出來后調(diào)用,我們可以選擇view.post()方法來實現(xiàn)美澳,比如:

```

//設(shè)置下劃線長度

tabLayout.post(new Runnable() {

@Override

? ? public void run() {

? ? ? setIndicator(tabLayout,60,60);

? ? }

});

```

到此這種方法就搞定啦销部,這個時候再運行程序你就會看到效果:

效果圖

這種思路是設(shè)置tabView的padding為0,并且設(shè)置了margin制跟,其實這種方案是錯誤的舅桩,他并沒有真正的去修改指示器寬度,而且它影響了tabview之間的間距雨膨,如果tabview多的話會被擠出去擂涛,它僅限于字數(shù)一樣的原因是:如果字數(shù)不一樣,tablayout會強制設(shè)置tabView的寬度為 幾個tabView中最寬的寬度,比如4個字的tabview和2個字的tabview的組合聊记,兩個tabview的寬度j將會強制為4個字的tabview的寬度撒妈。

因此這種解決方法適用性很差,像這種tabview個數(shù)不多的情況倒是可以使用這種排监。接下來我們看看第二種方法:

第二種:在第一種基礎(chǔ)上改進狰右,適應(yīng)性相對好很多

首先我們看默認的效果是什么樣的:


未做修改時效果圖

剛開始我們就提到了,源碼中 線的寬度是根據(jù) tabView的寬度來設(shè)置的舆床,那我們可以根據(jù)這個來入手棋蚌,通過反射拿到SlidingTabStrip,再通過遍歷拿到tabview挨队,繼續(xù)通過反射拿到textview谷暮,然后設(shè)置Tabview的寬度為textview的寬度,這樣就改變了指示器的寬度:看代碼

```

public void setIndicatorWidth(final TabLayout tabLayout){

//從源碼得知 線的寬度是根據(jù) tabView的寬度來設(shè)置的

? ? tabLayout.post(new Runnable() {

@Override

? ? ? ? public void run() {

try {

//拿到tabLayout的mTabStrip屬性

? ? ? ? ? ? ? ? LinearLayout mTabStrip = (LinearLayout)tabLayout.getChildAt(0);

? ? ? ? ? ? ? ? //將dp轉(zhuǎn)換成px

? ? ? ? ? ? ? ? int dp10 = MiscUtil.dipToPx(tabLayout.getContext(), 10);

? ? ? ? ? ? ? ? for (int i =0; i < mTabStrip.getChildCount(); i++) {

View tabView = mTabStrip.getChildAt(i);

? ? ? ? ? ? ? ? ? ? //拿到tabView的mTextView屬性? tab的字數(shù)不固定一定用反射取mTextView

? ? ? ? ? ? ? ? ? ? Field mTextViewField = tabView.getClass().getDeclaredField("mTextView");

? ? ? ? ? ? ? ? ? ? mTextViewField.setAccessible(true);

? ? ? ? ? ? ? ? ? ? TextView mTextView = (TextView) mTextViewField.get(tabView);

? ? ? ? ? ? ? ? ? ? tabView.setPadding(0, 0, 0, 0);

? ? ? ? ? ? ? ? ? ? //想要的效果是? 字多寬線就多寬盛垦,所以測量mTextView的寬度

? ? ? ? ? ? ? ? ? ? int width =0;

? ? ? ? ? ? ? ? ? ? width = mTextView.getWidth();

? ? ? ? ? ? ? ? ? ? if (width ==0) {

mTextView.measure(0, 0);

? ? ? ? ? ? ? ? ? ? ? ? width = mTextView.getMeasuredWidth();

? ? ? ? ? ? ? ? ? ? }

//設(shè)置tab左右間距 湿弦,因為源碼中線的寬度是根據(jù)tabView的寬度來設(shè)置的,所以得注意這里不能使用Padding

? ? ? ? ? ? ? ? ? ? LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();

? ? ? ? ? ? ? ? ? ? //指示器寬度值設(shè)置

? ? ? ? ? ? ? ? ? ? params.width = width;

? ? ? ? ? ? ? ? ? ? //設(shè)置一下tabview的margin腾夯,不設(shè)置會連在一起

? ? ? ? ? ? ? ? ? ? params.leftMargin = dp10;

? ? ? ? ? ? ? ? ? ? params.rightMargin = dp10;

? ? ? ? ? ? ? ? ? ? tabView.setLayoutParams(params);

? ? ? ? ? ? ? ? ? ? tabView.invalidate();

? ? ? ? ? ? ? ? }

}catch (NoSuchFieldException e) {

e.printStackTrace();

? ? ? ? ? ? }catch (IllegalAccessException e) {

e.printStackTrace();

? ? ? ? ? ? }

}

});

}

```

然后在Tablayout渲染出來后調(diào)用此方法即可省撑。我們看看效果


設(shè)置后效果圖

現(xiàn)在的效果就變成了字多寬指示器就多寬了赌蔑。

這個效果我也是思考了挺久的,參考許多前輩的經(jīng)驗竟秫,總結(jié)了這篇文章,中間是否會有其他問題暫時還沒有發(fā)現(xiàn)跷乐,大家要是有什么更好的辦法肥败,請評論指教一番,后續(xù)有什么問題我將及時更新的愕提。另外熱烈歡迎大家來留言討論馒稍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浅侨,隨后出現(xiàn)的幾起案子纽谒,更是在濱河造成了極大的恐慌,老刑警劉巖如输,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼓黔,死亡現(xiàn)場離奇詭異,居然都是意外死亡不见,警方通過查閱死者的電腦和手機澳化,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稳吮,“玉大人缎谷,你說我怎么就攤上這事≡钏疲” “怎么了列林?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長酪惭。 經(jīng)常有香客問我希痴,道長,這世上最難降的妖魔是什么撞蚕? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任润梯,我火速辦了婚禮,結(jié)果婚禮上甥厦,老公的妹妹穿的比我還像新娘纺铭。我一直安慰自己,他們只是感情好刀疙,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布舶赔。 她就那樣靜靜地躺著,像睡著了一般谦秧。 火紅的嫁衣襯著肌膚如雪竟纳。 梳的紋絲不亂的頭發(fā)上撵溃,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音锥累,去河邊找鬼缘挑。 笑死,一個胖子當著我的面吹牛桶略,可吹牛的內(nèi)容都是我干的语淘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼际歼,長吁一口氣:“原來是場噩夢啊……” “哼惶翻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鹅心,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤吕粗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旭愧,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颅筋,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年榕茧,在試婚紗的時候發(fā)現(xiàn)自己被綠了垃沦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡用押,死狀恐怖肢簿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜻拨,我是刑警寧澤池充,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站缎讼,受9級特大地震影響收夸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜血崭,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一卧惜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夹纫,春花似錦咽瓷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至月匣,卻和暖如春钻洒,著一層夾襖步出監(jiān)牢的瞬間奋姿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工素标, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留称诗,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓头遭,卻偏偏與公主長得像粪狼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子任岸,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容