简介
TabLayout:顾名思义,就是能够提供给我们标签页功能的控件。它通常用于与
ViewPager 联合使用,使界面具备滑动切换标签功能(TabLayout 本身已提供接口无缝结合 ViewPager 使用)。
来看下 TabLayout 的官方文档描述:
![](https://img.haomeiwen.com/i2222997/3837068ca6cbea31.png)
可以看到,TabLayout 存在于 design 包中,且继承于 HorizontalScrollView,提供了一个水平布局去显示标签页面。
TabLayout 的常用属性和方法
TabLayout 除了 Android 控件固有的属性(以 android: 为命名空间)之外,还定义了些特有的属性(是以 ”app:” 的命名空间的,形如app:tabMode),下面罗列一些使用相对频繁的属性:
属性 | 描述 |
---|---|
app:tabMode | 设置标签(tab)布局模式。有如下两种选项: "fixed":默认值,表示标签页不能滚动。一般用于标签较少的情况,每个 Tab 可以平分屏幕宽度。 "scrollable":表示标签页可以滚动展示。使用于标签文本过长和过多标签页这些情况。该模式通常在结合 ViewPager 中使用。当使用该属性时, tabGravity 的设置就不起作用了,标签都是从左向右布局。对应代码方法:setTabMode(int) |
app:tabGravity | 设置标签页(tab)对齐方式。有如下两种选项: "fill":所有标签页(tab)填满 TabLayout 宽度,该选项只有在 app:tabMode="fixed" 的时候才生效 。"center":标签页居中显示。 对应代码方法:setTabGravity(int) |
app:tabTextColor | 未选中标签页时,字体的颜色 |
app:tabSelectedTextColor | 选中标签页时,字体的颜色 |
app:tabIndicatorColor | 滑动时,指示器的颜色 |
app:tabIndicatorHeight | 设置指示器高度 |
app:tabBackground | 标签页(tab)布局背景 |
app:tabTextAppearance | 设置标签页标题文字样式 |
app:tabPadding | 标签页内边距 |
app:tabContentStart | 标签页(tab)左边距内容偏移量,该选项只有在app:tabMode="scrollable" 时才生效 |
app:tabMaxWidth | 标签页最大宽度 |
app:tabMinWidth= | 标签页最小宽度 |
下面罗列 TabLayout 一些相对重要的方法:
方法 | 描述 |
---|---|
newTab() | 创建一个新的标签 |
addTab(Tab) | 添加标签页 |
removeTab(Tab) | 删除标签页 |
removeTabAt(int) | 通过索引,删除标签页 |
removeAllTabs() | 删除所有标签页 |
getTabCount() | 返回标签页数量 |
getTabAt(int) | 返回索引对应的标签 页 |
getSelectedTabPosition() | 返回当前选中的标签页索引,若未选中,则返回 -1 |
addOnTabSelectedListener(OnTabSelectedListener) | 添加监听器 |
removeOnTabSelectedListener(OnTabSelectedListener) | 移除监听器 |
clearOnTabSelectedListeners() | 清除所有的监听器 |
addView |
TabLayout 是一个ViewGroup ,所以可以直接添加子View
|
setupWithViewPager(ViewPager) |
TabLayout 和 ViewPager 关联,随着 ViewPager 滑动而切换标签。 注:TabLayout 与 ViewPager 关联后,TabLayout 的标签页(tab)数量由 ViewPager 分页数量决定,TabLayout 的标签内容由 ViewPager的 Adapter 中getPagerTitle() 方法返回的内容决定 |
示例
- 直接为 TabLayout 添加标签(tab):
TabLayout tabLayout = ...;
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
可以看到:newTab 就是创建一个新的标签,然后通过 addTab 添加该标签到 TabLayout 中。
当然也可以直接在布局文件中指定标签,但是实际开发中一般不这样用:
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<android.support.design.widget.TabItem
android:text="@string/tab_text"/>
<android.support.design.widget.TabItem
android:icon="@drawable/ic_android"/>
</android.support.design.widget.TabLayout>
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
从上面的布局中,我们可以看出,布局很简单,就只包含 TabLayout 和 ViewPager,且 TabLayout 的特有属性均使用默认值。
然后再来看下源码:
public class TabLayoutActivity extends AppCompatActivity {
private static final int TAB_NUM = 3;
@BindView(R.id.viewpager)
private ViewPager mViewPager;
@BindView(R.id.tablayout)
private TabLayout mTabLayout;
private List<Fragment> mFragments;
@Override
@ViewInject(ViewInject.ACTIVITY)
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
initData();
initView();
}
private void initData() {
this.mFragments = new ArrayList<>();
}
private void initView() {
// generate Fragmetns
for (int i = 0; i < TabLayoutActivity.TAB_NUM; ++i) {
this.mFragments.add(MyFragment.newInstance("Fragmetn: " + i));
}
// set up adapter for ViewPager
this.mViewPager.setAdapter(new FragmentPagerAdapter(this.getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return TabLayoutActivity.this.mFragments.get(position);
}
@Override
public int getCount() {
return TabLayoutActivity.this.mFragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return "Tab" + position;
}
});
// connect TabLayout and ViewPager
this.mTabLayout.setupWithViewPager(this.mViewPager);
}
}
首先是创建3个Fragment
,然后给 ViewPager 设置一个FragmentPagerAdapter
,将先前创建的Fragment
通过该Adapter
设置给 ViewPager。最后通过setupWithViewPager
将 TabLayout 和 ViewPager 关联起来。
上述代码的效果如下:
![](https://img.haomeiwen.com/i2222997/58c5ad554adf14ec.gif)
更多代码详情,请查看:TODO::
接下来,我们改变一下 TabLayout 的app:tabMode
和app:tabGravity
,来看下效果有什么不同:
-
app:tabMode="fixed"
且app:tabGravity="center"
,效果如下:
![](https://img.haomeiwen.com/i2222997/58c5ad554adf14ec.gif)
可以看到跟我们上面的示例是一摸一样的,也就是app:tabMode="fixed"
和app:tabGravity="center"
就是默认的值。
-
app:tabMode="fixed"
且app:tabGravity="fill"
,效果如下:
![](https://img.haomeiwen.com/i2222997/50c02f74e914a680.gif)
可以看到,因为app:tabMode="fixed"
表示标签无法滚动,而app:tabGravity="fill"
表示填满标签(tab),因此这里的效果就是标签页均分填满了 TabLayout。
- 前面我们说过,当
app:tabMode="scrollable"
时,tabGravity
的设置就不起作用了,所以我们直接来看下app:tabMode="scrollable"
的效果:
![](https://img.haomeiwen.com/i2222997/ff24e237021f915d.gif)
可以看到,app:tabMode="scrollable"
时,标签页布局默认都是从左往右排列的。
一般使用app:tabMode="scrollable"
都是用于标签过多的情况的,此时,可以通过滑动标签来进行选择,效果如下所示:
![](https://img.haomeiwen.com/i2222997/a90140271dd44622.gif)
总结:
-
当
app:tabMode="fixed"
时,若app:tabGravity="center"
,则标签居中显示;若app:tabGravity="fill"
时,则标签均分填满 TabLayout。 -
当
app:tabMode="scrollable"
时,app:tabGravity
不起作用,默认标签布局为从左往右排列,该属性一般用于标签过多情况,可以通过直接滑动标签进行选取。
最后,如果我们想把标签放置到布局底部,应该怎样做呢?
其实很简单,只需更改布局如下:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" /> //占用上面,留出位置给TabLayout
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:tabGravity="fill"
app:tabIndicatorHeight="0dp" //因为默认指示器在下面,不合适使用在底部菜单所以直接设置其高度为0
app:tabMode="fixed"
app:tabSelectedTextColor="#FFFFFF"
app:tabTextColor="#000000" />
</LinearLayout>
效果如下:
![](https://img.haomeiwen.com/i2222997/5fa2688f98c34427.gif)
网友评论