<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年就从这篇博客开始吧~ 有问题请留言,方便的话 , 帮忙顶一下,谢谢!
<Android 基础(三十四)> TabLayout 从头到脚的更多相关文章
- Android笔记三十四.Service综合实例二
综合实例2:client訪问远程Service服务 实现:通过一个button来获取远程Service的状态,并显示在两个文本框中. 思路:如果A应用须要与B应用进行通信,调用B应用中的getName ...
- <Android 基础(十四)> selector
介绍 A StateListDrawable is a drawable object defined in XML that uses a several different images to r ...
- Bootstrap <基础三十二>模态框(Modal)插件
模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. 如果您想要单独引用该插件的功能,那么您需要引用 ...
- Bootstrap <基础三十>Well
Well 是一种会引起内容凹陷显示或插图效果的容器 <div>.为了创建 Well,只需要简单地把内容放在带有 class .well 的 <div> 中即可.下面的实例演示了 ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
- JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫
JAVA之旅(三十四)--自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫 我们接着来说网络编程,TCP 一.自定义服务端 我们直接写一个服务端,让本机去连接 ...
- Gradle 1.12用户指南翻译——第三十四章. JaCoCo 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- spring boot 常见三十四问
Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...
- Java15-java语法基础(十四)抽象类
Java15-java语法基础(十四)抽象类 一.抽象类的作用 三个类都有"执行任务"的方法,分别在这三个类中进行定义,因此需要重复编写代码,降低了程序开发效率,且增加了程序出现错 ...
- “全栈2019”Java多线程第三十四章:超时自动唤醒被等待的线程
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
随机推荐
- sync.WaitGroup和sync.Once
sync.WaitGroup,顾名思义,等待一组goroutinue运行完毕.sync.WaitGroup声明后即可使用,它有如下方法: func (wg *WaitGroup) Add(delta ...
- [POC]K8 DLLhijack Test
POC: 2016.11 Winrar却持 XP资源管理器却持 DLL却持VS全版本 https://www.cnblogs.com/k8gege/p/10261254.html POC:https: ...
- mysql 常用操作命令
mysql官网指南:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html 1.导出整个数据库mysqldump -u 用户名 -p --defa ...
- 基于GTK+3 开发远程控制管理软件(C语言实现)系列 一 开篇
近期趁公司没项目来,想学习一下C和GTK+3 ,顺道再学习一下Linux下有关网络编程方面的知识. 一.学习知识: 1.C基本语法 2.GTK+3 API学习 GUI相关知识学习 3.Glade使用及 ...
- url最后的“/”是什么作用
多了个尾巴 有时候,当你尝试在地址栏输入https://123/demo的时候,会发现浏览器会重定向到https://123/demo/这个地址,也就是多了个/,发生了重定向.有图为证: 上面这个图是 ...
- discuz 文件模板edit
1.修改title Power by discuz! 位置:template/default/common --->header_common.htm 2.discuz.htm 文件路径(修 ...
- tomcat8 进入不了Manager App 界面 403 Access Denied
准备 1.注释掉context.xml中的value属性 使用下面的命令: vim /usr/local/tomcats/tomcat-daily/webapps/manager/META-INF/c ...
- 最短路径算法----floyd(转)
一.Floyd算法 假设从i到j的最短路径上要经过若干个顶点,这些中间顶点中最大的顶点编号为k,最小的顶点为t,因此要求算dist[i][j]的最小值,那么只需要求算dist[i][s]+dist[s ...
- MySQL问答整理
1.Mysql中有哪些不同的表格? MyISAM: 基于IASM代码.可以被压缩,支持全文搜索,事务不安全,而且也不支持外键.如果事务回滚将会造成不完全回滚,从而不具备原子性.所以假如忽略事务以及访问 ...
- Spring @ModelAttribute
正文开始之前,先介绍个东西,Spring能够自动将请求参数封装到对应JavaBean上! 代码比较简单,也没有什么配置要记录,只是开启了<mvc:annotation-driven/>,可 ...