首先我要说的是TabLayout这个控件非常好用,随便搜索下网上一大堆的关于TabLayout的用法,因此我也就不具体介绍TabLayout的使用了。

这里我们谈谈为什么TabLayout无法自定义下划线宽度问题,废话不多说,上源码:

android tablayout选中字体变粗 tablayout宽度_tabLayout


首先找遍源码,对于下划线也代指TabLayout的指示器只提供了颜色和高度2个属性并没有找到宽度的设置,当然setMode除外。然后我们通过源码找到下划线的布局:

android tablayout选中字体变粗 tablayout宽度_tabLayout_02

我们发现SlidingTabStrip类是private修饰的,这样就没办法重写了,当然你也可以用反射来写,不过这不在本次文章范围之内,

再来看SlidingTabStrip暴露给外部的三个方法:

android tablayout选中字体变粗 tablayout宽度_控件_03


分别为setSelectedIndicatorColor(int color),setSelectedIndicatorHeight(int height) ,以及getIndicatorPosition()这三个方法,开始已经提到过,这三个方法对于修改宽度没什么关系。所以也略过,现在让我们来看SlidingTabStrip的onMeasure方法,其中有2段核心代码分别为:

android tablayout选中字体变粗 tablayout宽度_宽度_04

android tablayout选中字体变粗 tablayout宽度_赋值_05

首先来看第一段代码,largesTabWidth的大小取得是自身和子布局宽度较大的一个,程序会执行全部的数量的tab控件从而获取最大控件的宽度,然后将largesTabWidth赋值,好了这段代码的作用结束。

我们来看第二段代码的作用,在执行第二段代码的时候,largesTabWidth的值已经是最大的情况,这时系统又一次的遍历了所有的控件,并且比较了宽度,如果宽度部位0或者跟largesTabWidth不等(其实就是比largesTabWidth小),这时候便会强行给每个下划线赋值为largesTabWidth的值,而到目前为止,下划线的宽度取值都是tab的宽度来控制的。

从上面我们就能看出悲催的下划线无法掌控自己的宽度,那么宽高测量完了,下面再来看看下划线移动时动画过程的布局绘制:

android tablayout选中字体变粗 tablayout宽度_tabLayout_06

在draw方法里可以看到下划线的左右坐标分别为mIndicatorLeft和mIndicatorRight,这两个值怎么来的?一句话,上代码:

android tablayout选中字体变粗 tablayout宽度_tabLayout_07


在setIndicatorPosition(int left, int right)方法中,我们看到了什么?没错!悲催的下划线左右坐标又被left 和 right强行赋值了。而left 和 right的则是所选项tab的左右坐标,在下划线移动过程中根据位移大小进行动态的赋值。

看了这么多代码我们发现下划线不管是移动过程还是原始绘制过程都被tab管的死死的,TabLayout不可以进行自定义的下划线宽度,虽然灵活性上面差了点,但是却能够保证稳定性。总的来说TabLayout还是不错的。

业余时间用反射写了个开源框架LuBus,主要用于项目模块间解耦,需要的朋友可以看看,github地址https://github.com/luying6/LubusDemo