• <Android 基础(三十四)> TabLayout 从头到脚


    1. 简介

    1.TabLayout给我们提供的是一排横向的标签页

    2.#newTab()这个方法来创建新的标签页,然后用过#setText()和#setIcon方法分别修改标签页的文本和图标,创建完成之后,我们需要使用#addtab()方法把他加到TabLayout中显示出来

    3.第二种添加标签的方式就是直接在TabLayout布局下添加#TabItem控件

    4.对于TabLayout在标签之前的切换事件我们可以通过注册一个监听器来处理,#setOnTabSelectedListener(OnTabSelectedListener)

    5.TabLayout可以和ViewPager一起使用


    2. 自定义属性值

    TabLayout属性

    属性 意义
    tabGravity fill,填满TabLayout;center,居中显示
    tabMode fixed, 固定标签;scrollable,可滚动标签,个数较少的时候可以使用fixed,如果标签超出了屏幕范围,设置为scrollable比较好
    tabMaxWidth Tab的最大宽度
    tabIndicatorColor 底部滑动的线条的颜色,默认是colorAccent
    tabIndicatorHeight 底部滑动线条的高度
    tabPadding* 标签页的padding
    tabBackground 标签页的背景
    tabTextAppearance 文本设置
    tabSelectedTextColor 选中字体颜色

    TabItem属性

    属性 意义
    text 标签文字
    icon 图标
    layout 自定义布局

    3. 源码分析

    一点一点的看


    这里写图片描述

    类成员 稍微解释一下
    Mode MODE_SCROLLABLE, MODE_FIXED两种模式,一个是固定,一个是可滚动
    TabGravity GRAVITY_FILL, GRAVITY_CENTER,两种摆放方式,铺满和居中
    OnTabSelectedListener Tab切换事件的回调接口
    Tab类 对TabView进行的封装,给它加了一些属性,因为TabView无法对外暴露,相当于给外部提供一个调用的类,值得一提的是这个tag是一个object,所以可以往里面存放各种内容,传递数据的时候可能会有用
    TabLayoutOnPageChangeListener 继承 ViewPager.OnPageChangeListener用于与ViewPager联动,主要是indicator的动作和tab页的选中
    ViewPagerOnTabSelectedListener 继承TabLayout.OnTabSelectedListener,viewpager用来配合tablayout的页面切换事件

    这里写图片描述

    方法 稍微解释一下
    构造方法 不显示滚动条,创建标签条就是下面滚来滚去的那个东东,获取自定义属性值
    addTab 手动添加Tab页
    addOnTabSelectedListener/removeOnTabSelectedListener、clearOnTabSelectedListeners 添加/移除/清空Tab选择事件监听器
    newTab 创建Tab页
    getTabAt 通过index获取Tab
    removeTab 通过tab实例移除tab
    removeTabAt 移除特定位置的tab
    removeAllTabs 清空tabs
    setTabTextColors 设置tab的正常显示颜色和选中后颜色
    setupWithViewPager 通过ViewPager初始化TabLayout
    shouldDelayChildPressedState 判断是否需要delay视图的press状态,一般无法滚动的视图直接返回false,可以滚动的视图看情况返回true或者false
    addView 添加TabItem,如果参数类型不是TabItem会报异常
    generateLayoutParams 默认生成属性值,防止TabItem没有定义android:layout_*而报异常

    这里写图片描述
    结合上面的介绍,这些内容含义应该比较清晰了


    4. 简单使用

    不使用setupWithViewPager,与ViewPager联动

    布局文件

    <?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="onlyloveyd.com.indicatordemo.MainActivity">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tb_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorWhite"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabIndicatorHeight="4dp"
            app:tabMode="fixed"
            app:tabSelectedTextColor="@color/colorAccent"
            app:tabTextColor="@color/colorBlack">
    
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/one"
                android:text="社会"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/two"
                android:text="娱乐"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/three"
                android:text="体育"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/four"
                android:text="军事"/>
    
    
        </android.support.design.widget.TabLayout>
    
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    MainActivity

    public class MainActivity extends AppCompatActivity {
    
        @BindView(R.id.activity_main)
        LinearLayout activityMain;
        @BindView(R.id.vp_content)
        ViewPager vpContent;
        @BindView(R.id.tb_title)
        TabLayout tbTitle;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ButterKnife.bind(this);
            MainPagerAdapter mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
            vpContent.setAdapter(mainPagerAdapter);
            tbTitle.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(vpContent));
            vpContent.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tbTitle));
        }
    
    }

    关键点在最后两行代码

    tbTitle.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(vpContent));
    vpContent.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tbTitle));

    这两行代码来源于TabLayout的setupWithViewPager方法,目的就是为了实现ViewPager和TabLayout的联动,但是也不用removeAllTabs,看过这部分源码的朋友应该都知道,setupWithViewPager方法中先清除tab,然后根据ViewPager的getPagerTitle返回的字符串创建文字Tab并且添加到TabLayout中用于与ViewPager联动,这就是为啥很多初学者在使用setupWithViewPager的时候出现tab页无法显示的问题一般原因都是自己添加了tab或者是在布局文件中定义了TabItem但是使用的时候调用了setupWithViewPager方法,但是ViewPager的Adapter又没有复写getPagerTitle方法,因为这个方法在PagerAdapter中实默认返回null的。同时还有一个弊端就是setupWithViewPager并不支持图标显示。,原因就是:

    这里写图片描述
    而在populateFromPagerAdapter的实现中

        void populateFromPagerAdapter() {
            removeAllTabs();//一开始就把全部的tab给干掉
    
            if (mPagerAdapter != null) {
                final int adapterCount = mPagerAdapter.getCount();//获取ViewPager的数量
                for (int i = 0; i < adapterCount; i++) {
                    addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);//只拿title,没有设置icon
                }
    
                // Make sure we reflect the currently set ViewPager item
                if (mViewPager != null && adapterCount > 0) {
                    final int curItem = mViewPager.getCurrentItem();
                    if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                        selectTab(getTabAt(curItem));
                    }
                }
            }
        }

    实际效果

    这里写图片描述


    使用setupWithViewPager,与ViewPager联动

    既然setupWithViewPager会清除TabItem,那么我们就不添加TabItem,让它自己处理吧

    布局文件去掉上个例子中的四个TabItem


    MainActivity中去掉后面两行,换成如下一行代码

    tbTitle.setupWithViewPager(vpContent);

    实际效果
    这里写图片描述

    虽说setupWithViewPager本身的实现过程是不支持Icon的显示的,但是我们可以自己动手,一个简单的循环解决问题,实现的效果与上面4.1节相同

    for(int index = 0 ; index< tbTitle.getTabCount(); index++) {
        TabLayout.Tab tab = tbTitle.getTabAt(index);
        tab.setIcon(MainPagerAdapter.mIcons[index]);
    }

    5. 自定义Layout的TabItem

    图标+文字

    布局文件

    <?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="onlyloveyd.com.indicatordemo.MainActivity">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tb_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorWhite"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabIndicatorHeight="4dp"
            app:tabMode="fixed"
            app:tabSelectedTextColor="@color/colorAccent"
            app:tabTextColor="@color/colorBlack">
    
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/one"
                android:layout="@layout/custom_indicator"
                android:text="社会"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout="@layout/custom_indicator2"
                android:icon="@drawable/two"
                android:text="娱乐"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout="@layout/custom_indicator3"
                android:icon="@drawable/three"
                android:text="体育"/>
            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:icon="@drawable/four"
                android:text="军事"/>
        </android.support.design.widget.TabLayout>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    使用自定义布局
    android:layout=”@layout/custom_indicator”
    android:layout=”@layout/custom_indicator2”
    android:layout=”@layout/custom_indicator3”

    custom_indicator.xml文件内容,值得注意的是这里的TextView的id必须是“@android:id/text1”,ImageView的id必须是“@android:id/icon”,原因来自于与TabLayout的源码中TabView的update方法。
    这里写图片描述

    custom_indicator.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content">
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            />
        <ImageView
            android:id="@android:id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            />
    </LinearLayout>

    其他的两个文件和这个类似,只是位置调整了一哈子。


    实际效果
    这里写图片描述

    6. 写在最后

    2017年就从这篇博客开始吧~ 有问题请留言,方便的话 , 帮忙顶一下,谢谢!

  • 相关阅读:
    .net core 在 Docker 上的部署
    js 运算的内置函数
    vux 项目的构建
    微信小程序开发资料
    HttpClient 调用WebAPI时,传参的三种方式
    jsplumb 中文教程
    MyEclipse最新版-版本更新说明及下载
    如何用VSCode调试Vue.js
    vs2017开发Node.js控制台程序
    Objc的底层并发API
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467148.html
Copyright © 2020-2023  润新知