TabLayout 修改指示线长度

TabLayout

TabLayout: 属于Material Design库下的控件,在Android开发中使用频率还是比较高的。

基本使用

1
compile 'com.android.support:design:25.3.1'

配合ViewPager使用

创建xml文件,在文件中配置tabLayoutviewPager,官方文档的例子:

1
2
3
4
5
6
7
8
9
10
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top" />

</android.support.v4.view.ViewPager>

创建 fragmentFragmentPagerAdapter 适配器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private class ReChargeAdapter extends FragmentStatePagerAdapter {
//test code
String[] title = {"Hexo", "Java", "Android"};

private ReChargeAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int position) {
int type;
switch (position){
case 0:
type = Constants.TYPE_A;
break:
case 1:
type = Constants.TYPE_B;
break:
case 2:
type = Constants.TYPE_C;
break:
default:
type = Constants.TYPE_A;
break:
}
return Fragment.newInstance(type);
}

@Override
public int getCount() {
return null == title ? 0 : title.length;
}

@Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
AttachActivity 设置
1
tabLayout.setupWithViewPager(viewPager); 设置与 viewPager 联动

几个基本属性

1
tabSelectedTextColor 被选中 tab 的字体颜色
1
tabIndicatorHeight 指示条的高度
1
tabIndicatorColor 指示条的颜色
1
tabMode fixed 即标题固定,scrollable 为标题滚动
1
tabGravity fill 填充布局,center 居中显示
1
tabBackground 标题背景

修改 TabLayout 指示条长度

 TabLayout 没有现成的 Api 可以修改指示条的长度,实际项目中常常要求指示条与标题文字长度保持一致。网上有几种办法,只能基本满足,如果严格匹配需要借助第三方库。
 stackoverflow 上有几种办法可以参考。自己在项目中是通过反射修改,只能粗略满足:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void setIndicatLength(TabLayout tab, int leftMargin, int rightMargin) {
Class<?> tabLayout = tab.getClass();
Field strip = null;
try {
strip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}

if (null != strip) {
strip.setAccessible(true);
LinearLayout linearLayout = null;
try {
linearLayout = (LinearLayout) strip.get(tab);
} catch (IllegalAccessException e) {
e.printStackTrace();
}

int marginLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftMargin, Resources.getSystem().getDisplayMetrics());
int marginRight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightMargin, Resources.getSystem().getDisplayMetrics());

if (null != linearLayout) {
for (int i = 0; i < linearLayout.getChildCount(); i++) {
View child = linearLayout.getChildAt(i);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
child.setPadding(0, 0, 0, 0);
params.leftMargin = marginLeft;
params.rightMargin = marginRight;
child.setLayoutParams(params);
child.invalidate();
}
}
}
}

初始化时调用:

1
2
TabLayout tabLayout = findViewById(R.id.tab_layout);
setIndicatLength(tabLayout, 20, 20);

为什么是 “mTabStrip”

 查看 TabLayout 的源码可以发现,mTabStrip的本质是一个LinearLayout,是个私有的变量,正是这个变量控制了 TabLayout 下指示条的长度与 tabItemLayoutParams。而反射可以在运行时获得mTabStrip变量,从而修改指示条长度。也就解释了反射中的:

1
strip = tabLayout.getDeclaredField("mTabStrip");

TabLayout源码中的变量 mTabStrip 如图:
mfC1gO.jpg

mTabStrip的作用:
mfCGKe.jpg

这个功能是摆设,看看就好~~~