<Android 基础(三十四)> TabLayout 从头到脚
2017-01-02 20:33
344 查看
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 Layout研究 <一> 基础知识
- Android 使用<include /> 标签来重用layout代码
- 【Android基础 007】 <meta-data>使用方法
- <java基础>零起点学Android(三)
- Android Layout研究 <四> 实例
- 从零開始学android<RelativeLayout相对布局.十六.>
- <java基础>零起点学Android(二)Intent 意图
- 从零开始学android<RelativeLayout相对布局.十六.>
- <java基础>零起点学Android(五)之应用窗口
- Android Layout研究 <三> View的布局方式及实例
- Android 表格布局<TableLayout>
- 从零开始学android<popupwindow弹出式窗口.三十四.>
- Android UI 优化 [ 类别:Layout ] <merge>的学习
- android面试题目大全<第二部分>,java基础部分
- Android 编程基础<一>
- android基础学习<二>--->Activity的来龙去脉
- <Android>构建一个ListView基础版
- Android Fragment 学习<2> 滑动TAb导航(无ActionBar)
- 从零开始学android<Tablelayout表格布局.十五.>