Android TabLayout控件

2023-11-15

前言

TabLayout是5.0版本出现的控件,显示水平方向的tab页。需要添加Design依赖库,并且使用Theme.AppCompat主题。

1. TabLayout类

布局文件

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:background="@color/white"/>

利用addTab(Tab)newTab()方法添加tab页

TabLayout tabLayout = findViewById(R.id.tab_layout1);
tabLayout.addTab(tabLayout.newTab().setText("tab1"));
tabLayout.addTab(tabLayout.newTab().setText("tab2"));
tabLayout.addTab(tabLayout.newTab().setText("tab3"));

效果如下
在这里插入图片描述

2. 主要参数

  • tabSelectedTextColor,改变选中字体的颜色
  • tabTextColor,未选中字体的颜色
  • tabTextAppearance,字体大小
    app:tabSelectedTextColor="#FFFF8800"
    app:tabTextColor="#FFCCCCCC"
    app:tabTextAppearance="@style/tabLayoutTextAppearance"
    
    在这里插入图片描述
  • tabIndicatorColor,指示器下标的颜色
  • tabIndicatorHeight,指示器下标的高度
    app:tabIndicatorColor="#FFFF8800"
    app:tabIndicatorHeight="4dp"
    
    在这里插入图片描述
  • tabGravity,内容显示方式center(内容居中显示)和fill(内容尽可能充满)
    在这里插入图片描述
  • tabModetab选项卡的行为模式,fixed(tab固定)和scrollable(tab可滑动)
    在这里插入图片描述
  • tabBackground,背景
  • tabContentStart,相对起始位置tabY轴偏移量
  • tabPaddingtab的内边距
  • tabPaddingStarttab的左侧内边距
  • tabPaddingEndtab的右侧内边距
  • tabPaddingToptab的顶部内边距
  • tabPaddingBottomtab的底部内边距
  • tabMaxWidthtab选项卡的最大宽度
  • tabMinWidthtab选项卡的最小宽度

3. TabLayout主要方法

  • addTab(Tab),向此布局添加选项卡
  • addView(View),添加子视图
  • addOnTabSelectedListener(OnTabSelectedListener),添加监听器
  • newTab(),创建一个新的tab
  • setTabTextColors(int, int),设置用于选项卡的不同状态的文本颜色
  • setSelectedTabIndicatorColor(int),设置选中的tab的指示器颜色
  • setSelectedTabIndicatorHeight(int),设置选中的tab的指示器的高度
  • setTabGravity(int),设置TabLayout的布局方式
  • setTabMode(int),设置tab选项卡的行为模式
  • setupWithViewPager(ViewPager, boolean),将TabLayoutViewPager绑定在一起

4. 自定义TabItem

在配置文件中指定TabItem

<android.support.design.widget.TabLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:background="@color/white">
    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="tab1"/>

    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="tab2"
        android:icon="@mipmap/ic_launcher"/>

    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_tab_item1"/>

</android.support.design.widget.TabLayout>

layout_tab_item1.xml文件

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="tab4"
    android:gravity="center"/>

调用Tab.setCustomView(int)方法

tabLayout.addTab(tabLayout.newTab().setCustomView(R.layout.layout_tab_item2));

效果如下
在这里插入图片描述

5. TabLayout代码分析

TabLayout.newTab()方法

public Tab newTab() {
    // sTabPool是一个数据池,保存Tab  
    Tab tab = sTabPool.acquire();
    if (tab == null) {
        tab = new Tab();
    }
    tab.mParent = this;
    // createTabView 方法创建一个`TabView`
    tab.mView = createTabView(tab);
    return tab;
}

private TabView createTabView(@NonNull final Tab tab) {
    // mTabViewPool同样是个数据池,用来保存TabView
    TabView tabView = mTabViewPool != null ? mTabViewPool.acquire() : null;
    if (tabView == null) {
        tabView = new TabView(getContext());
    }
    // 设置tab内容
    tabView.setTab(tab);
    tabView.setFocusable(true);
    tabView.setMinimumWidth(getTabMinWidth());
    return tabView;
}

TabView继承LinearLayout

public TabView(Context context) {
    super(context);
    if (mTabBackgroundResId != 0) {
        ViewCompat.setBackground(
                this, AppCompatResources.getDrawable(context, mTabBackgroundResId));
    }
    ViewCompat.setPaddingRelative(this, mTabPaddingStart, mTabPaddingTop,
            mTabPaddingEnd, mTabPaddingBottom);
    setGravity(Gravity.CENTER);
    setOrientation(VERTICAL);
    setClickable(true);
    ViewCompat.setPointerIcon(this,
            PointerIconCompat.getSystemIcon(getContext(), PointerIconCompat.TYPE_HAND));
}

void setTab(@Nullable final Tab tab) {
    if (tab != mTab) {
        mTab = tab;
        update();
    }
}

final void update() {
    final Tab tab = mTab;
    // 是否是自定义View
    final View custom = tab != null ? tab.getCustomView() : null;
    if (custom != null) {
        final ViewParent customParent = custom.getParent();
        if (customParent != this) {
            if (customParent != null) {
                ((ViewGroup) customParent).removeView(custom);
            }
            addView(custom);
        }
        mCustomView = custom;
        // 设置默认不可见
        if (mTextView != null) {
            mTextView.setVisibility(GONE);
        }
        if (mIconView != null) {
            mIconView.setVisibility(GONE);
            mIconView.setImageDrawable(null);
        }

        mCustomTextView = (TextView) custom.findViewById(android.R.id.text1);
        if (mCustomTextView != null) {
            mDefaultMaxLines = TextViewCompat.getMaxLines(mCustomTextView);
        }
        mCustomIconView = (ImageView) custom.findViewById(android.R.id.icon);
    } else {
        // We do not have a custom view. Remove one if it already exists
        if (mCustomView != null) {
            removeView(mCustomView);
            mCustomView = null;
        }
        mCustomTextView = null;
        mCustomIconView = null;
    }

    // 如果没有自定义View,使用默认ImageView和TextView
    if (mCustomView == null) {
        // If there isn't a custom view, we'll us our own in-built layouts
        if (mIconView == null) {
            ImageView iconView = (ImageView) LayoutInflater.from(getContext())
                    .inflate(R.layout.design_layout_tab_icon, this, false);
            addView(iconView, 0);
            mIconView = iconView;
        }
        if (mTextView == null) {
            TextView textView = (TextView) LayoutInflater.from(getContext())
                    .inflate(R.layout.design_layout_tab_text, this, false);
            addView(textView);
            mTextView = textView;
            mDefaultMaxLines = TextViewCompat.getMaxLines(mTextView);
        }
        TextViewCompat.setTextAppearance(mTextView, mTabTextAppearance);
        if (mTabTextColors != null) {
            mTextView.setTextColor(mTabTextColors);
        }
        updateTextAndIcon(mTextView, mIconView);
    } else {
        // Else, we'll see if there is a TextView or ImageView present and update them
        if (mCustomTextView != null || mCustomIconView != null) {
            updateTextAndIcon(mCustomTextView, mCustomIconView);
        }
    }

    // Finally update our selected state
    setSelected(tab != null && tab.isSelected());
}

TabLayout.addTab(Tab, int, boolean)方法

public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
    if (tab.mParent != this) {
        throw new IllegalArgumentException("Tab belongs to a different TabLayout.");
    }
    configureTab(tab, position);
    addTabView(tab);

    if (setSelected) {
        tab.select();
    }
}

// 配置Tab
private void configureTab(Tab tab, int position) {
    tab.setPosition(position);
    mTabs.add(position, tab);

    final int count = mTabs.size();
    for (int i = position + 1; i < count; i++) {
        mTabs.get(i).setPosition(i);
    }
}

private void addTabView(Tab tab) {
    final TabView tabView = tab.mView;
    mTabStrip.addView(tabView, tab.getPosition(), createLayoutParamsForTabs());
}

TabLayout.addView(View)方法会调用addViewInternal(View)方法,child必须是TabItem类型。

private void addViewInternal(final View child) {
    if (child instanceof TabItem) {
        addTabFromItemView((TabItem) child);
    } else {
        throw new IllegalArgumentException("Only TabItem instances can be added to TabLayout");
    }
}

private void addTabFromItemView(@NonNull TabItem item) {
    final Tab tab = newTab();
    if (item.mText != null) {
        // 会调用TabView.update修改
        tab.setText(item.mText);
    }
    if (item.mIcon != null) {
        // 会调用TabView.update修改
        tab.setIcon(item.mIcon);
    }
    if (item.mCustomLayout != 0) {
        // 会调用TabView.update修改
        tab.setCustomView(item.mCustomLayout);
    }
    if (!TextUtils.isEmpty(item.getContentDescription())) {
        tab.setContentDescription(item.getContentDescription());
    }
    addTab(tab);
}

TabItem类,可以指定texticon,也可以自定义layout

public final class TabItem extends View {
    final CharSequence mText;
    final Drawable mIcon;
    final int mCustomLayout;

    public TabItem(Context context) {
        this(context, null);
    }

    public TabItem(Context context, AttributeSet attrs) {
        super(context, attrs);

        final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
                R.styleable.TabItem);
        mText = a.getText(R.styleable.TabItem_android_text);
        mIcon = a.getDrawable(R.styleable.TabItem_android_icon);
        mCustomLayout = a.getResourceId(R.styleable.TabItem_android_layout, 0);
        a.recycle();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android TabLayout控件 的相关文章

随机推荐

  • 两个多项式相加算法(链表实现)

    来源 数据结构期中考试补充题 注 该代码测试数据较少 吃过晚饭有时间再测试下改改bug QAQ 多项式相加 include
  • Python3运行报错:TypeError: Object of type ‘type‘ is not JSON serializable解决方法(不是针对对象转Json的方法)

    问题描述 Python内置的json模块提供了非常完善的Python对象到JSON格式的转换 json dumps 将Python中的对象转换为JSON中的字符串对象 json loads 将JSON中的字符串对象转换为Python中的对象
  • OpenSystemArchitect从入门到放弃

    原因 pd每次建立外键都自动生成字段 这个设置找不到解决方案 就想着有不有替代pd的工具 结果百度 还真有 用OpenSystemArchitect的原因 开源免费 他的外键直观的展示2个表的关系 逻辑视图的支持 放弃 文档不全 好多问题没
  • YUM仓库及NFS共享服务理论

    文章目录 一 YUM仓库 1 YUM概述 2 准备安装源 3 访问YUM仓库 二 FNS共享存储服务 1 NFS概念 2 NFS使用场景 3 NFS服务 一 YUM仓库 1 YUM概述 YUM Yellow dog Updater Modi
  • Allegro添加相对传输延迟的等长规则设置

    怎么去添加相对传输延迟的等长规则 首先讲述的是通过直接添加法去添加 直接添加法只适用于点对点的传输模式 中间没有任何串阻 串容的情况 具体操作如下所示 01 打开规则管理器 打开规则管理器 执行菜单命令Setup Constraints 在
  • 抖之恒科技python常用库之工具库schema

    在Python编程语言中 有众多的开源库可以帮助程序员更加高效地完成各种任务 其中 Schema就是一款非常实用的工具库之一 本文将为您介绍Schema库的基本概念 使用方法以及它在Python编程中重要性 一 什么是Schema Sche
  • Koin入门使用

    一 简单流程 1 创建Koin容器 startKoin 创建一个Koin容器并注册到GlobalContext中 modules module 配置Koin模块并注入到Koin容器 2 创建Koin模块 class People val k
  • HDU1007(最近点对问题)

    题意不难理解 就是找到最近的两个点 计算其距离 除以2就是所求的圆的半径 思路很简单 运用分治的思想 先划分区间 分别找到左右区间中的最近点对 再合并区间 找到区间间的最近点对 注意如果用qsort 进行排序可能会超时 include
  • Qi v1.2.4 -- WPC官方文档资源下载

    WPC无线充电联盟QI协议1 2 4 zip qi 嵌入式文档类资源 CSDN下载QI协议part1 part2 part3 part4完整版 没有积分可使用链接 链接 httpqi更多下载资源 学习资料请访问CSDN下载频道 https
  • 剑指offer-42翻转单词顺序-左旋转字符串

    先来一道简单题 将字符串左旋 输入abcdefg 输出cdefgab package Leetcode Author YCKJ3803 Date 2021 3 1 16 41 Description public class Zuoxuan
  • Java概述(了解java开发及背景)

    目录 一 java语言背景介绍 Java 语言的三个版本 JavaSE JavaME JavaEE 二 Java跨平台原理 三 JRE和JDK Java 程序开发的三个步骤 编写代码 编译代码 运行代码 JDK JRE 和 JVM 的关系
  • 初学JAVA的变量作用域

    变量的范围是程序中该变量可以被引用的部分 方法内定义的变量被称为局部变量 局部变量的作用范围从声明开始 直到包含它的块结束 局部变量必须声明才可以使用 方法的参数范围涵盖整个方法 参数实际上是一个局部变量 for循环的初始化部分声明的变量
  • 简单springboot及springboot cloud环境搭建

    springboot使用特定的方式 简化了spring的各种xml配置文件 并通过maven或者gradle 完成所需依赖 使用springboot maven插件 可直接输出可运行的jar包 省去了tomcat等容器的部署 使得基于htt
  • 基于Sqli-Labs靶场的SQL注入-29~31关

    目录 Less 29 基于GET 双服务器 单引号 字符型注入 双服务器解析 爆破数据库名 爆破表名 爆破列名 爆破字段值 Less 30 基于GET 双服务器 双引号 字符型注入 Less 31 基于GET 双服务器 双引号加括号 字符型
  • Java Web: JDBC、数据库连接池、Maven

    1 JDBC JDBC 全称Java DataBase Connection Java 数据库连接 在前面我们已经学习过Java和DataBase 数据库 了 JDBC就是使用Java语言操作关系型数据的一套API 本质上就是一个接口 用于
  • java实现 手写体识别_java手写体英文数字识别系统 识别预处理如何实现 采用什么语言比较好...

    展开全部 转载 1 引言 手写体数字识别是文字识别中的一个研究课题 是多年来的研究热点 也是模62616964757a686964616fe4b893e5b19e31333337373638式识别领域中最成功的应用之一 由于识别类型较少 在
  • 微信小程序:横向滚动卡片列表模板

    文章目录 1 前言 2 代码详解 3 样例展示 4 结语 1 前言 在开发微信小程序时 横向可滚动卡片列表是一个必不可缺的页面组件 其不仅美观还可以节省屏幕空间 具体截图如下 2 代码详解 主要用的是scroll x 具体代码如下 wxml
  • 开启win10下Ubuntu子系统的SSH服务 并设置为开机启动

    Win10中安装Ubuntu子系统后默认是没有开启SSH服务的 需要手动配置开启 1 先通过 bash 进入子系统修改配置 vi etc ssh sshd config 备注 输入i 表示键入 按键 ESC 外加 冒号 WQ 退出保存 如果
  • 笔记,后期整理

    VM 虚拟各种系统的工具 安装目录 不要放在C盘 需要下载的镜像Windows NT win7 xp server08R2 server12类Nnix centos 6 7 8 ubuntu 14 16 18 kali安装 win7 1g
  • Android TabLayout控件

    前言 TabLayout是5 0版本出现的控件 显示水平方向的tab页 需要添加Design依赖库 并且使用Theme AppCompat主题 1 TabLayout类 布局文件