TabLayout是Android.support.design.widget.TabLayout
包下面的一个控件,使用它可以很简单的实现tab导航功能,可以解决大部分情况,只是这个控件开放的API不多,本文主要介绍如何在TabLayout基础上实现UI的定制。
推荐阅读
本文不是介绍TabLayout用法,详细使用请移步Android 新特性 - TabLayout
效果
实现的效果类似给每个tab加上小红点显示,偷懒没做小红点,用ImageView代替一下
xml中使用TabLayout
<android.support.design.widget.TabLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
app:tabMode="fixed"
app:tabGravity="center"
android:layout_height="50dp"
android:id="@+id/tably"/>
item_tab的布局文件
android:textColor="@color/selector_tab"
是一个选择器
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/black" android:state_selected="false"/>
<item android:color="#f00" android:state_selected="true"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="qqq"
android:textColor="@color/selector_tab" />
<ImageView
android:layout_width="10dp"
android:id="@+id/iv"
android:layout_height="10dp"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
添加自定义View
View tab1View = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
Text tv1 = tab1View.findViewById(R.id.text1);
tv1.setText("测试1");
View tab2View = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
Text tv2 = tab2View.findViewById(R.id.text1);
tv1.setText("测试2");
TabLayout.Tab tabA = tabLayout.newTab().setCustomView(tab1View);
tabLayout.addTab(tabA);
TabLayout.Tab tabB = tabLayout.newTab().setCustomView(tab2View);
tabLayout.addTab(tabB);
更改状态
- 很尴尬的是使用
setCustomView()
之后,TabLayout原先的颜色变化都没有了,所以需要自己来实现,在监听中动态更改状态
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
for(int i=0;i<2;i++){
if(tab.getPosition() == i){
TextView viewById = (TextView) tab.getCustomView().findViewById(R.id.text1);
viewById.setTextColor(Color.RED);
}else {
TextView viewById = (TextView) tabLayout.getTabAt(i).getCustomView().findViewById(R.id.text1);
viewById.setTextColor(Color.BLACK);
}
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
优化实现
- 每次选中的时候去
findView
,多少有点浪费资源。而且代码也不友好,使用Holder来持有控件,就不需要每次都查找了,代码也简化了很多
class MyTabHolder {
TextView tv;
ImageView iv;
View parent;
public MyTabHolder(View parent, String txt) {
this.parent = parent;
this.tv = (TextView) parent.findViewById(R.id.text1);
this.iv = (ImageView) parent.findViewById(R.id.iv);
this.tv.setText(txt);
}
}
map = new ArrayMap<>();
map.put(0, new MyTabHolder("测试1"));
map.put(1, new MyTabHolder("测试2"));
tabLayout.addTab(tabLayout.newTab().setCustomView(map.get(0).parent)); tabLayout.addTab(tabLayout.newTab().setCustomView(map.get(1).parent));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
for (int i = 0; i < map.keySet().size(); i++) {
map.get(i).tv.setSelected(i == tab.getPosition());
}
}
});