Android Design Support Library之TabLayout

常规使用

效果预览


注:tab2 和tab4 需要自定义。

Gradle

app/build.gradle 中添加下面依赖:

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

xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="center">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:icon="@drawable/custom_tab_icon"
android:layout_height="wrap_content"
android:text="Tab1" />
</android.support.design.widget.TabLayout>
  • TabLayout 属性
    tabBackground:标签页的背景;
    tabMode:fixed, 固定标签,tab均分,适合少的tab;scrollable,可滚动标签,适合很多tab,默认fixed;
    tabTextColor:标签字体颜色;
    tabSelectedTextColor:标签选中字体颜色;
    tabIndicatorColor:底部滑动的线条的颜色,默认是colorAccent;
    tabIndicatorHeight:底部滑动线条的高度。

  • TabItem 属性
    text:标签文字;
    icon:图标;
    layout:自定义布局。

由上可知在 xml 可以增加 tab,当然也是可以代码中添加:

1
tabLayout.addTab(tabLayout.newTab().setText("Tab3"));

TabItem 可以设置 layout 来自定义布局,后文讲。

OnTabSelectedListener

tab 点击回调监听:

1
2
3
4
5
6
7
8
9
10
11
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

与 ViewPager 联动

效果预览

xml布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@color/colorPrimary"
app:tabSelectedTextColor="@color/white"
app:tabTextColor="@color/cursorTextColor" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

ViewPager的适配器

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
Fragment newfragment = new TodayEmotionFragment();
Bundle data = new Bundle();
data.putInt("id", 0);
newfragment.setArguments(data);
adapter.addFrag(newfragment,"Tab1");
newfragment = new TodayEmotionFragment();
data = new Bundle();
data.putInt("id", 1);
newfragment.setArguments(data);
adapter.addFrag(newfragment, "Tab2");
newfragment = new TodayEmotionFragment();
data = new Bundle();
data.putInt("id", 1);
newfragment.setArguments(data);
adapter.addFrag(newfragment,"Tab3");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
}

设置联动

1
2
3
4
5
6
7
8
9
10
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewPager);
setupViewPager(viewPager);
// 设置ViewPager的数据等
tabLayout.setupWithViewPager(viewPager);
}

定义 TabLayout 样式

上面的效果图,tab2 和 tab4 是需要自定义的,自定义可以直接写在 TabItem 的 xml 的 layout 属性:

1
2
3
4
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout="@layout/custom_tab1" />

也可以写在代码里:

1
2
3
4
5
6
View view = View.inflate(this, R.layout.custom_tab1, null);
TextView tabText = (TextView) view.findViewById(R.id.tabText);
tabText.setText("Tab4");
TextView tabPoint = (TextView) view.findViewById(R.id.tabPoint);
tabPoint.setText("9");
tabLayout.addTab(tabLayout.newTab().setCustomView(view));

问题


如上,我看了 TabLayout 的源码,发现自定义 View 这里的 text 和 icon的 id 是写死了,意思我自定义的这两个 id 要相应写死,我的 custom_tab1.xml

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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="72dp"
android:layout_height="72dp"
android:minWidth="56dp">
<ImageView
android:id="@+id/tabIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:background="@drawable/custom_tab_icon"
android:scaleType="centerInside" />
<TextView
android:id="@+id/tabText"
style="@style/TextAppearance.Design.Tab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tabIcon"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/custom_tab_text" />
<TextView
android:id="@+id/tabPoint"
android:layout_width="20dp"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_height="20dp"
android:background="@drawable/tab_point_bg"
android:layout_alignParentRight="true"
android:textColor="@color/tab_point_text" />
</RelativeLayout>

如果我 text 和 icon 写死成源码的 id,tab 反而不显示,我随便写,是可以,纳闷,它是如何 findViewById 到的?

最后,不要问我,icon 的大小和 text 的字体颜色和字体大小为什么写这么多,我也不知道,是拷的源码。另外,还有选中时 icon 和 text 的效果,需要自己写的,具体请看下面的我给的 sample。

源码地址

https://github.com/WuXiaolong/DesignSupportLibrarySample

更新日志

  • 2017-08-20 更新
  • 2015-08-03 撰写


联系作者

我的微信公众号:吴小龙同学,欢迎关注交流,公号回复关键字「1024」有惊喜哦。