本文CSDN博客php
本文简书java
在布局里加入 TabLayout,默认是下划线的样式,可使用 tabIndicatorGravity
属性设置为:bottom
(默认值,能够不用设置,指示器显示在底部)、 top
(指示器显示在顶部)、center
(指示器显示在中间)、stretch
(指示器高度拉伸铺满 item)。android
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="@color/colorPrimary"
app:tabIndicatorFullWidth="true"
<!-- 设置 Indicator 高度 -->
app:tabIndicatorHeight="2dp"
app:tabMode="scrollable" />
复制代码
注意 app:tabIndicatorFullWidth="true"
属性,设为 true,是 Indicator 充满 item 的宽度:git
设为 false 是 Indicator 保持和 item 的内容宽度一致:github
网上的作法通常是经过反射来设置 Indicator 的宽度,能够参见博客: 关于Android改变TabLayout 下划线(Indicator)宽度实践总结app
不过我以为可使用 layer-list
来实现。 在 drawable
文件夹下新建一个 indicator.xml
文件:源码分析
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
<!-- 设置左边距 -->
android:left="15dp"
<!-- 设置右边距 -->
android:right="15dp">
<!-- 注:这里须要一个空的 <shape /> 标签,不然会报错 -->
<shape />
</item>
</layer-list>
复制代码
须要注意的是在 shape 里设置颜色是无效的,须要在布局文件里设置 Indicator 颜色。布局
在 TabLayout
布局里添加 Indicator 的样式:this
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<!-- 设置 Indicator 高度 -->
app:tabIndicatorHeight="2dp"
<!-- 设置 Indicator 颜色 -->
app:tabIndicatorColor="@color/colorPrimary"
<!-- 设置 Indicator 的样式 -->
app:tabIndicator="@drawable/indicator"
app:tabMode="scrollable" />
复制代码
若是不须要边距,只须要圆角,能够配合 app:tabIndicatorFullWidth
属性,使用 shape
设置 app:tabIndicator
来实现圆角便可,无需使用 layer-list
,代码就不用贴了吧~spa
这里为了使效果看得明显一点,把 Indicator 的高度设置为 5dp。 给 Indicator 添加了 5dp 的圆角:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="15dp" android:right="15dp">
<shape>
<corners android:radius="5dp" />
</shape>
</item>
</layer-list>
复制代码
<shape>
的 <size>
标签里设置宽高(API 23 以上):<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 若不设置 gravity,则 Indicator 宽度会填满整个 item -->
<item android:gravity="center_horizontal">
<shape>
<corners android:radius="5dp" />
<size android:width="20dp" android:height="5dp" />
</shape>
</item>
</layer-list>
复制代码
layer-list
里给 <item>
标签设置宽高(API 23 以上):<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="20dp"
android:height="5dp"
<!-- 若不设置 gravity 则默认是居左显示,须要设置为水平居中显示 -->
android:gravity="center_horizontal">
<shape>
<corners android:radius="5dp" />
</shape>
</item>
</layer-list>
复制代码
TabLayout
的 tabIndicator
属性里设置的 layer-list
不支持设置颜色。 咱们查看一下 TabLayout
的源码,搜索 TabLayout_tabIndicator
:
this.setSelectedTabIndicator(MaterialResources.getDrawable(context, a, styleable.TabLayout_tabIndicator));
复制代码
setSelectedTabIndicator()
方法:
tabSelectedIndicator
的地方,在
SlidingTabIndicator
类里的
draw()
方法里: 第 1 处
tabSelectedIndicator
selectedIndicatorHeight
是什么:
selectedIndicatorHeight
是在布局里给
TabLayout
设置的
tabIndicatorHeight
属性。
可见若是咱们在布局里给 TabLayout
设置了 tabIndicatorHeight
属性,则 Indicator 高度优先取 tabIndicatorHeight
设置的高度;不然才会取我们自定义的 drawable
里的高度。
继续,第 2 处 tabSelectedIndicator
drawable
里设置的颜色无效了,由于使用的是
TabLayout_tabIndicatorColor
属性里设置的颜色,因此
<stroke>
也无效,只保留了总体的形状样式。
若是须要复杂一点的样式,好比 <stroke>
。 先写一个 tab 被选中时的样式 indicator.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
<!-- 设置边距 -->
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp">
<shape>
<!-- 设置圆角 -->
<corners android:radius="5dp" />
<!-- 设置边框 -->
<stroke
android:width="1dp"
android:color="@color/colorAccent" />
</shape>
</item>
</layer-list>
复制代码
还须要一个 selector.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/indicator" android:state_selected="true" />
</selector>
复制代码
接下来,咱们要设置的是 tabBackground
,也就是 tab 标签的背景,而再也不是tabIndicator
,因此要把 Indicator 的高度设为 0 ,不使用 tab 原生的 Indicator。
这里还要注意一下 tabRippleColor
属性,是设置点击 tab 标签时的波纹颜色,不设置的时候,默认是灰色的,文章前面的截图里有显示效果。若是想去掉这个效果,设置颜色为透明便可。
<android.support.design.widget.TabLayout
android:id="@+id/tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
<!-- 使用咱们自定义的点击样式 -->
app:tabBackground="@drawable/selector"
<!-- tabIndicator 高度设为 0 -->
app:tabIndicatorHeight="0dp"
app:tabMode="scrollable"
<!-- 设置点击时的波纹颜色为透明 -->
app:tabRippleColor="@android:color/transparent" />
复制代码
附上一个效果图,感受仍是很酷炫的: