Material Design系列教程(8) - TabLayout

简介

TabLayout:顾名思义,就是能够提供给我们标签页功能的控件。它通常用于与
ViewPager 联合使用,使界面具备滑动切换标签功能(TabLayout 本身已提供接口无缝结合 ViewPager 使用)。

来看下 TabLayout 的官方文档描述:

《Material Design系列教程(8) - TabLayout》 TabLayout

可以看到,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) TabLayoutViewPager 关联,随着 ViewPager 滑动而切换标签。
TabLayoutViewPager 关联后,TabLayout 的标签页(tab)数量由 ViewPager 分页数量决定,TabLayout 的标签内容由 ViewPagerAdaptergetPagerTitle()方法返回的内容决定

示例

 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>

从上面的布局中,我们可以看出,布局很简单,就只包含 TabLayoutViewPager,且 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。最后通过setupWithViewPagerTabLayoutViewPager 关联起来。

上述代码的效果如下:

《Material Design系列教程(8) - TabLayout》 TabLayout default value

更多代码详情,请查看:TODO::

接下来,我们改变一下 TabLayoutapp:tabModeapp:tabGravity,来看下效果有什么不同:

  • app:tabMode="fixed"app:tabGravity="center",效果如下:

《Material Design系列教程(8) - TabLayout》 tabMode=”fixed”`且`tabGravity=”center”`

可以看到跟我们上面的示例是一摸一样的,也就是app:tabMode="fixed"app:tabGravity="center"就是默认的值。

  • app:tabMode="fixed"app:tabGravity="fill",效果如下:

《Material Design系列教程(8) - TabLayout》 tabMode=”fixed”`且`tabGravity=”fill”`

可以看到,因为app:tabMode="fixed"表示标签无法滚动,而app:tabGravity="fill"表示填满标签(tab),因此这里的效果就是标签页均分填满了 TabLayout

  • 前面我们说过,当app:tabMode="scrollable"时,tabGravity的设置就不起作用了,所以我们直接来看下app:tabMode="scrollable"的效果:

《Material Design系列教程(8) - TabLayout》 app:tabMode=”scrollable”

可以看到,app:tabMode="scrollable"时,标签页布局默认都是从左往右排列的。

一般使用app:tabMode="scrollable"都是用于标签过多的情况的,此时,可以通过滑动标签来进行选择,效果如下所示:

《Material Design系列教程(8) - TabLayout》 app:tabMode=”scrollable”

总结

  • 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>

效果如下:

《Material Design系列教程(8) - TabLayout》 TabLayout_bottom

参考

    原文作者:Whyn
    原文地址: https://www.jianshu.com/p/2042f5bf9122
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞