前言
今天给大家带来Material design系列的第四篇文章,TabLayout的使用,首先说明一下,什么是TabLayout,这里引用一下源码中对TabLayout的介绍
TabLayout provides a horizontal layout to display tabs.
意思很明确,TabLayout提供了一个水平的布局用来展示Tabs。
那么在开发中相信大家在开发中经常会看到这样的ui
像这样多个tab切换,其实就可以用TabLayout来实现。
使用
首先在你的布局文件中加入该控件
然后在代码中找到控件,并给他设置几个tab
做到这一步你就能看到这样的效果(PS:刚出iPhone8,我也来蹭一波热度)
是不是很简单,你只需要做这么一点操作就能实现tab切换的效果。
结合ViewPager使用
当然,在开发中,我们一般都是结合ViewPager来使用达到切换的目的,那么怎么做呢?
首先在布局文件中加入ViewPager控件
然后在代码中找到该控件
附上adapter代码
private class DemoPager extends FragmentPagerAdapter {
private final List<Fragment> fragments;
private final List<String> titles;
public DemoPager(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments == null ? 0 : fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
做到这一步,我们就可以看到这样的效果。
TabLayout属性介绍
-
app:tabSelectedTextColor:改变选中字体的颜色
-
app:tabTextColor:改变未选中字体的颜色
-
app:tabIndicatorColor:改变指示器颜色
-
app:tabBackground:改变背景色
-
app:tabIndicatorHeight:改变指示器高度
这五个属性我都使用了,这里给大家看看效果(前方高能,非战斗人员请迅速撤离)
哈哈,这个配色虽然有点辣眼睛,不过这不是重点,效果实现了就好,毕竟我们是开发人员,不是UI对吧,o(∩_∩)o 哈哈。
-
添加图标
如果只是文字,可能会有点单调,我们可以加一个图标在上面,就像这样,调用getTabAt拿到对应的tab,然后调用setIcon方法即可
-
app:tabMode
这个属性的作用就是修改TabLayout的属性,有2个值,fixed和scrollable,默认是fixed,fixed就是固定的,scrollable就是可以滑动,举个栗子,我先多加几个标题
-
app:tabGravity:内容的显示模式,center是居中,fill是填满
-
app:tabMaxWidth:tab最大宽度
-
app:tabMinWidth:tab最小宽度
-
app:tabContentStart:tab的"margin"
TabLayout的监听事件
修改指示器长度
相信用过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();
}
tabStrip.setAccessible(true);
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabs);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
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();
}
}
然后你只需要在拿到tablayout之后调用一下该方法就好,就像这样
效果图
添加分割线
这个需求并不多,但是如果碰到了,那就乖乖的做吧。。。
//先拿到tablayout
LinearLayout linearLayout = (LinearLayout) tabLayout.getChildAt(0);
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
//传入一张图片,我这里就用shape代替了
linearLayout.setDividerDrawable(ContextCompat.getDrawable(this,
R.drawable.divider));
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/red"/>
<size android:width="2dp"/>
</shape>
自定义视图setCustomView
比如我们要实现tab有两行文字的需求,如果文字大小都相同,我们直接用\n换行就可以实现,就像这样
如果上面textView字体大小与下面不同,或者一些奇奇怪怪的需求,那么就需要用到setCustomView了。
先给大家看一下效果图
这样的效果你用单纯的\n肯定是实现不了的对吧。
这里给大家贴一下上述需求实现的代码,大家可以做一个参考应用到自己的项目里面
//先把你要的标题放到集合中
List<String> topTitles = new ArrayList<>();
topTitles.add("java");
topTitles.add("php");
topTitles.add("python");
List<String> bottomTitles = new ArrayList<>();
bottomTitles.add("c语言");
bottomTitles.add("c++");
bottomTitles.add(".net");
//其次添加几个tab
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
tabLayout.addTab(tabLayout.newTab());
//通过getTabCount方法拿到tab的数量
int tabCount = tabLayout.getTabCount();
for (int i = 0; i < tabCount; i++) {
View view = View.inflate(this, R.layout.custom_view, null);
((TextView) view.findViewById(R.id.tv_top)).setText(topTitles.get(i));
((TextView) view.findViewById(R.id.tv_bottom)).setText(bottomTitles.get(i));
//调用setCustomView方法设置自定义布局
tabLayout.getTabAt(i).setCustomView(view);
}
自定义布局文件我就不贴了,就是两个TextView而已。
这里要注意了,当你这样做了之后,app:tabSelectedTextColor和app:tabTextColor属性就失效了,我们需要手动解决这个问题,给tablayout设置一个监听
手动设置之后,确实能实现颜色切换的效果,但是这里还有一个问题,不知道大家发现没有,那就是你必须挨个点击之后,颜色改变才能生效,那么怎么办呢,这里刚开始想到的是调用
mTabLayout.getTabAt(0).select();
手动选择第一个tab,但是发现这样并不能达到效果,所以最终的解决方案是这样的
拿到listener对象,手动调用里面的方法,这样效果就能实现了
总结
好了,TabLayout的使用到此结束了,祝大家工作顺心,看到这里了你还不点赞,你的良心不会痛么(┬_┬)