美文网首页Materia...
Material Design系列教程(8) - TabLayo

Material Design系列教程(8) - TabLayo

作者: Whyn | 来源:发表于2018-06-27 00:25 被阅读178次

    简介

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

    来看下 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 添加标签(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>
    

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

    上述代码的效果如下:

    TabLayout default value

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

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

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

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

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

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

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

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

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

    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>
    

    效果如下:

    TabLayout_bottom

    参考

    相关文章

      网友评论

        本文标题:Material Design系列教程(8) - TabLayo

        本文链接:https://www.haomeiwen.com/subject/ytxvyftx.html