当我们要实现多个tab切换时,当然可以自己布局去实现,但这个需要自己处理一些事情(比如下划线的滑动等,虽然这也不难),更简单的实现方式就是使用TabLayout去实现,下面我来总结一下TabLayout的使用。

一、使用步骤

1、导入support依赖:

compile 'com.android.support:design:25.3.1'

在导入support包的时候可能会导致65536超出方法数的异常,请参考 异常com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

2、布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"><android.support.design.widget.TabLayoutandroid:id="@+id/tab_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#ffffff"app:tabGravity="fill"app:tabMode="fixed"app:tabIndicatorColor="@color/main"app:tabIndicatorHeight="@dimen/p4"app:tabSelectedTextColor="@color/main"app:tabTextColor="#898989"app:tabTextAppearance="@style/TextAppearance.AppCompat.Menu"/><android.support.v4.view.ViewPagerandroid:id="@+id/pager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/></LinearLayout></layout>

上面是一个简单但通用的 TabLayout + ViewPager 布局页面,由于我使用了databinding框架,所以外面多了一层layout标签。TabLayout的属性我不做过多解释。

3、设置主题样式

如果按照现在这样运行,会异常,因为TabLayout需要设置样式

Theme.AppCompat

既可以在清单文件中设置,也可以代码设置,为了通用,我是代码设置的:

setTheme(R.style.Theme_AppCompat);

注意必须在setContentView()之前设置才有效。

4、设置tab和ViewPager

    protected void setTitleAndContent(List<String> titles, ArrayList<Fragment> fragments) {if (titles == null || titles.size() <= 0 || fragments == null || fragments.size() <= 0) {ToastViewUtil.showShort(mContext, "标题和内容不能为空!");return;}if (titles.size() != fragments.size()) {ToastViewUtil.showShort(mContext, "标题和内容数目不一致!");return;}mBinding.tabLayout.setupWithViewPager(mBinding.pager);mBinding.pager.setAdapter(new AdapterTabPagerFragment(getSupportFragmentManager(), fragments));mBinding.pager.addOnPageChangeListener(this);for (int i=0; i<titles.size(); i++) {mBinding.tabLayout.getTabAt(i).setText(titles.get(i));}}

这里注意,setupWithViewPager()必须在tab的setText()之前,不然tab上面的内容会显示不出来。

ViewPager滑动事件绑定tab选择:

    @Overridepublic void onPageSelected(int position) {mBinding.tabLayout.getTabAt(position).select();}

5、一个蛋疼的问题

这个时候运行程序,你会发现tab下面的下划线很长,它的宽度是跟tab的宽度一致的,然而并没有方法设置下划线的宽度。OMG。。。。。这个时候自定义控件的优势显现出来了,想设多长就设多长。

然而,这等问题是难不倒天朝程序员的,百度一下,发现大家解决这个问题的方案基本都是通过反射的方式设置下划线的margin,我把这个方法做了优化,让下划线永远是tab宽度的一半,先计算的tab的宽度,这个简单,就是屏幕宽度除以tab数量:

tabIndicatorWidth = getWindowManager().getDefaultDisplay().getWidth() / (2 * titles.size());

修改后的设置下划线宽度的方法:

/*** 设置下标线的宽度** @param tabs*/public void setIndicatorWidth(TabLayout tabs) {Class<?> tabLayout = tabs.getClass();Field tabStrip = null;try {tabStrip = tabLayout.getDeclaredField("mTabStrip");} catch (NoSuchFieldException e) {e.printStackTrace();}tabStrip.setAccessible(true);LinearLayout llTab = null;try {llTab = (LinearLayout) tabStrip.get(tabs);} catch (IllegalAccessException e) {e.printStackTrace();}for (int i = 0; i < llTab.getChildCount(); i++) {View child = llTab.getChildAt(i);child.setPadding(0, 0, 0, 0);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);params.leftMargin = tabIndicatorWidth / 2;params.rightMargin = tabIndicatorWidth / 2;child.setLayoutParams(params);child.invalidate();}}

这里是通过设置leftMargin和rightMargin来间接设置下划线的宽度。

由于需要在UI绘制完成之后调用该方法才有用,所以使用post()方法来调用该方法:

        mBinding.tabLayout.post(new Runnable() {@Overridepublic void run() {setIndicatorWidth(mBinding.tabLayout);}});

其他问题:

1、tab的字体大小不能直接精确设置,只能通过

app:tabTextAppearance="@style/TextAppearance.AppCompat.Menu"

来设置。

参考:

Design库-TabLayout属性详解

TabLayout使用相关推荐

  1. TabLayout的指示器长度 的问题

    刚开始效果图 修改后的效果图 这个效果实现 就是在 tablayout 的xml 里面添加 app:tabIndicatorFullWidth="false"

  2. TabLayout 在宽屏幕上tab不能平均分配的问题解决

    TabLayout 在屏幕比较宽的屏幕上的时候 ,不如平板,特质的屏幕的时候 tabMode="fixed" 这个时候就是失效了 显示失效了 是居中的效果 这个修改方法就是在xml ...

  3. Tablayout 多个界面使用一个fragment 的实例

    这个主要还是adapter 里面 添加list 就行了 这里直接上代码吧 ,我刚写的demo 看的时候看adapter 就行了 布局代码: <?xml version="1.0&quo ...

  4. Tablayout 修改默认选项页,或者跳转到指定的选项页

    tablayout 的默认选项页为 viewpage.setCurrentItem(0) 如果想修改为第二页 viewpage.setCurrentItem(1) 即可 如果是根据跳转的情况来跳到不同 ...

  5. TabLayout 遇到那些坑 tab标签不显示问题

    别人写的参考下,知道问题所在 如何使用 :注意事项 <?xml version="1.0" encoding="utf-8"?> <Relat ...

  6. android自定义tab下划线变大,Android开发之设置TabLayout下方下划线的宽度

    由于最近项目需要,需要设置tabLayout下方下划线的长度.笔者上网找了半天,也没有找到方法.后来了解到在源码中对tabLayout的下划线进行了设置.并没有方法可以直接设置. 然后,笔者看到了某位 ...

  7. Android Studio 第五十期 - 自定义TabLayout

    代码已经整理好,效果如下图: code1: <com.ui.widget.UnAnimTabLayoutandroid:id="@+id/tab"android:layout ...

  8. TabLayout+ViewPager+Fragment中Fragment的可见和不可见问题

    场景 TabLayout+ViewPager+Fragment的使用过程中需要判断Fragment是否对用户可见,监听Fragment由不可见变为可见的事件 解决方案 重写Fragment的setUs ...

  9. Android tabLayout+recyclerView实现锚点定位

    原文链接:https://mp.weixin.qq.com/s/L3o2i3WTmg1ScXEYDS8YCg 在上一篇文章 [Android 实现锚点定位 ](https://mp.weixin.qq ...

  10. ViewPager,TabLayout,Fragment实现tabs滑动

    工作半年了,准备在新的一年开始写点博客,记录自己的成长,如果能给别人一些参考就更好了. Demo实现: 前段时间公司的项目遇到了使用 ViewPager,TabLayout 和 Fragment实现一 ...

最新文章

  1. centos7.2安装mysql 1
  2. 英伟达公开课 | 手把手教你部署一辆高速目标检测Jetbot智能小车
  3. Spring Aop实例之xml配置
  4. Mybatis的修改列与重命名
  5. c++ 数组置0_0基础学习C语言第七章:数组(1)
  6. css表单发光,表单input选中后发光CSS怎么写
  7. Windows句柄-2
  8. 作者:项连城(1992-),女,中国科学院自动化研究所硕士生
  9. 微信小程序获取当前地址以及选择地址详解 地点标记
  10. oracle中master实例,Oracle10g/11g RAC数据库中的Master实例、Owner实例和Past Image的概念PART2...
  11. BOW(opencv源码)
  12. fp算法例题_大部分人都理解错了的FPgrowth算法
  13. 08cms房产门户系统v8.4升级补丁支持新版APP和小程序
  14. 虚拟机安装Mac OS系统
  15. android高仿ios11系统,安卓仿苹果iOS11主题APP
  16. java rrd 读取_RRDtool 系列连载-6 :如何从 RRD 数据库中提取数据 - RRDtool - 阿勃的 blog...
  17. 利用Clonezilla备份还原Linux系统
  18. [翻译Pytorch教程]NLP从零开始:使用序列到序列网络和注意力机制进行翻译
  19. java怎样实现换肤功能_JavaScript实现换肤功能
  20. 误发邮件如何能撤回?

热门文章

  1. hduOJ(2003-2006)
  2. 4种数据分析基础方法,终于有人讲明白了
  3. 要输就输给追求,要嫁就嫁给幸福
  4. note4 android 7.0,三星手机安卓7.0升级名单曝光:S5、Note4无缘
  5. 壁纸姐来啦,好看壁纸图片,美女哈
  6. C语言LNK2019错误怎么解决,error LNK2019: 无法解析的外部符号 (解决方法)
  7. spring-security-oauth2(十) QQ登陆上
  8. 域名该怎样选_域名选择策略有哪些(教你如何选一个好的域名)
  9. arduino学习——WS2812灯带
  10. 极海纵横科技馆移动导览项目(物联网+定位技术等, APP+RFID项目)