前言

前面介绍了TabLayout的基本属性和基本的使用方法。我是传送门

真实的业务场景中,很多的效果,原生的TabLayout,并不支持。例如下滑线短于文字的效果,底部导航栏效果,标签文字选中是需要加粗效果等等。

所以我们需要使用TabLayout的自定义tab标签。

先上图。

先为急用的朋友上代码,后面做讲解

java类

  1. import android.content.Context;
  2. import android.os.Bundle;
  3. import android.support.design.widget.TabLayout;
  4. import android.support.v4.app.Fragment;
  5. import android.support.v4.app.FragmentManager;
  6. import android.support.v4.app.FragmentPagerAdapter;
  7. import android.support.v4.view.ViewPager;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.view.LayoutInflater;
  10. import android.view.View;
  11. import android.widget.CheckBox;
  12.  
  13. import java.util.ArrayList;
  14. import java.util.List;
  15.  
  16. import butterknife.BindView;
  17. import butterknife.ButterKnife;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. @BindView(R.id.vp_all)
  21. ViewPager vpAll;
  22. @BindView(R.id.tab_custom)
  23. TabLayout tabCustom;
  24.  
  25. //存放自定义tab标签的列表
  26. List<View> customTabList = new ArrayList<>();
  27. //存放对应tab标签的fragment页面
  28. List<PageFragment> fgList = new ArrayList<>();
  29. //选中的自定义标签,标记器。默认选中第一个。标记位是0;
  30. int indicator = 0;
  31.  
  32. ViewPagerAdapter pagerAdapter;
  33.  
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_main);
  38. ButterKnife.bind(this);//此处是用的是butterKnife框架,等同于findviewbyid获取各个控件。
  39. initTabCustomAndViewPager();
  40. initListener();
  41. }
  42.  
  43. /**
  44. * 初始化tab标签和viewpager内容。
  45. */
  46. private void initTabCustomAndViewPager() {
  47. //初始化10个自定义tab标签
  48. for (int i = 0; i < 10; i++) {
  49. final View tabView = getCustomTabView(this, "自定义" + i);
  50. customTabList.add(tabView);
  51. if (i==0){
  52. //设置默认第一个选中效果
  53. ((CheckBox) tabView.findViewById(R.id.cb_name)).setChecked(true);
  54. tabView.findViewById(R.id.cb_slide).setVisibility(View.VISIBLE);
  55. }
  56. tabCustom.addTab(tabCustom.newTab().setCustomView(tabView));
  57. }
  58. //初始化10个fragment页面
  59. for (int i = 0; i < 10; i++) {
  60. fgList.add(PageFragment.newInstance("我是内容栏目" + i));
  61. }
  62. pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fgList);
  63. vpAll.setAdapter(pagerAdapter);
  64. }
  65.  
  66. /**
  67. * 将viewpager和tabLayout之间的滑动事件和点击事件关联起来。
  68. * 此处不能使用tabLayout的setupWithViewPager()方法,否则会造成自定义view失效
  69. */
  70. private void initListener() {
  71. //添加关联接口,此处不能用自带的绑定方法,否则自定义view会失效
  72. vpAll.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  73. @Override
  74. public void onPageScrolled(int i, float v, int i1) {
  75. }
  76.  
  77. @Override
  78. public void onPageSelected(int i) {
  79. tabCustom.getTabAt(i).select();
  80. }
  81.  
  82. @Override
  83. public void onPageScrollStateChanged(int i) {
  84. }
  85. });
  86. tabCustom.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  87. @Override
  88. public void onTabSelected(TabLayout.Tab tab) {
  89. //viewpager联动
  90. vpAll.setCurrentItem(tab.getPosition());
  91. //将之前选中的tab标签,设置为未选中状态
  92. View oldView = customTabList.get(indicator);
  93. CheckBox oldCbName = (CheckBox) oldView.findViewById(R.id.cb_name);
  94. View oldCbSlide = oldView.findViewById(R.id.cb_slide);
  95. oldCbName.setChecked(false);
  96. oldCbSlide.setVisibility(View.INVISIBLE);
  97. //当前选中的tab标签,设置为选中状态。
  98. indicator = tab.getPosition();
  99. View newView = customTabList.get(indicator);
  100. CheckBox newCbName = (CheckBox) newView.findViewById(R.id.cb_name);
  101. View newCbSlide = newView.findViewById(R.id.cb_slide);
  102. newCbName.setChecked(true);
  103. newCbSlide.setVisibility(View.VISIBLE);
  104. }
  105.  
  106. @Override
  107. public void onTabUnselected(TabLayout.Tab tab) {
  108. }
  109.  
  110. @Override
  111. public void onTabReselected(TabLayout.Tab tab) {
  112. }
  113. });
  114.  
  115. }
  116.  
  117. /**
  118. * ViewPager的适配器。
  119. */
  120. class ViewPagerAdapter extends FragmentPagerAdapter {
  121.  
  122. List<PageFragment> fragmentList;
  123.  
  124. public ViewPagerAdapter(FragmentManager fm, List<PageFragment> fragmentList) {
  125. super(fm);
  126. this.fragmentList = fragmentList;
  127. }
  128.  
  129. @Override
  130. public Fragment getItem(int position) {
  131. return fragmentList.get(position);
  132. }
  133.  
  134. @Override
  135. public int getCount() {
  136. return fragmentList.size();
  137. }
  138. }
  139.  
  140. /**
  141. * 获取自定义Tab标签的显示的内容
  142. *
  143. * @param context
  144. * @param
  145. * @return
  146. */
  147. public static View getCustomTabView(Context context, String text) {
  148. View view = LayoutInflater.from(context).inflate(R.layout.item_custom_tab, null);
  149. CheckBox tabText = (CheckBox) view.findViewById(R.id.cb_name);
  150. tabText.setText(text);
  151. return view;
  152. }
  153. }

pageFragment的代码和布局就不贴了。不想写的朋友可以看上一篇:我是传送门

布局文件

activity_main的布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. tools:context="com.example.administrator.tablayoutdemo.MainActivity">
  9. <android.support.design.widget.TabLayout
  10. android:id="@+id/tab_custom"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. app:tabIndicatorHeight="0dp"
  14. app:tabMode="scrollable"
  15. />
  16.  
  17. <android.support.v4.view.ViewPager
  18. android:id="@+id/vp_all"
  19. android:layout_width="match_parent"
  20. android:layout_height="match_parent" />
  21.  
  22. </LinearLayout>

自定义tab标签的布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. android:paddingLeft="10dp"
  6. android:paddingRight="10dp"
  7. android:orientation="vertical"
  8. android:gravity="center"
  9. android:descendantFocusability="blocksDescendants">
  10. <CheckBox
  11. android:id="@+id/cb_name"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:button="@null"
  15. android:text=""
  16. android:textColor="@drawable/select_text_color"
  17. android:textSize="15sp"
  18. android:paddingTop="13dp"
  19. android:ellipsize="end"
  20. android:singleLine="true"
  21. android:maxEms="5"
  22. android:textStyle="bold"
  23. android:paddingBottom="13dp"
  24. android:clickable="false"
  25. />
  26. <View
  27. android:id="@+id/cb_slide"
  28. android:layout_width="20dp"
  29. android:layout_height="3dp"
  30. android:visibility="invisible"
  31. android:background="#ff4fbf86"/>
  32.  
  33. </LinearLayout>

色值文件select_text_color,放在drawable目录下

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:color="#ff4fbf86" android:state_checked="true"/>
  4. <item android:color="#BBBBBB" android:state_checked="false" />
  5. </selector>

讲解:

OK上完代码,针对关键点在做一次说明

1、标签在初始化的过程中,需要对第一个tab标签提前进行选中状态的初始化,否则可能会造成第一次启动的时候,第一个标签没有出现选中状态。

2、viewpager和TabLayout标签进行联动的时候,不可以使用TabLayout的setupWithViewPager()方法,而是要通过ViewPager的addOnPageChangeListener()和Tablayout的addOnTabSelectedListener()方法进行两个控件之间的联动效果。否则会造成自定义的CustomeTab被TabLayout默认生成的标签覆盖掉。

3、在布局文件中,需要将TabLayout的tabIndicatorHeight设为0。用来屏蔽掉控件自动生成的下滑线。

通过自定义的Tab标签可以完全实现自己控制tab标签的内容,这里就不展示tab标签做为底部导航栏的效果了。原理都是一样的。

TabLayout的高级使用的更多相关文章

  1. TabLayout基本使用

    前言 Tablayout继承自HorizontalScrollView,可以用作顶部标签效果.底部导航栏效果.一般多与ViewPager一起使用. 想直接了解如何实现短下滑效果的请看:TabLayou ...

  2. 重磅推出TabLayout高级窗口组件

    TabLayout是在APICloud现有窗口系统基础上升级而来的高级窗口组件,符合Material Design规范,可通过简单的配置为窗口实现原生的导航栏和TabBar,它将帮助您节省30%以上的 ...

  3. 高级UI晋升之常用View(三)中篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...

  4. doT的高级用法及loadData的使用

    本文出自APICloud官方论坛, 感谢论坛版主 gp3098的分享. 之前直接把模板写在页面底部的script标签内的,但是现在不同. 使用了doT.js配合api的loadData方法,整个页面就 ...

  5. MySQL高级知识- MySQL的架构介绍

    [TOC] 1.MySQL 简介 概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而 ...

  6. PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)

    100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...

  7. TabLayout + ViewPager

    一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0'compile 'com.android. ...

  8. 马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)

    马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)目录详情:18_02_ssl协议.openssl及创建私有CA18_03_OpenSSH服务及其相关应用09_01_磁盘及文 ...

  9. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

随机推荐

  1. [strongswan][autoconf][automake][cento] 在CentOS上编译strongswan git源码时遇到的autoconf问题

    编译strongswan的git源码问题 1. 概述 首先,我们想要通过源码编译strongswan.当满足以下条件时,通常你会遇见此问题: 源码时通过git clone的得来的,而不是官网下载的源码 ...

  2. Autofac之类型关联

    前面的学习一直使用的是直接注册类型并不是Autofac已经依赖注入的主要使用方式,最佳的依赖注入与Autofac的使用方式,都是要结合面向接口(抽象)编程的概念的.推崇的是依赖于抽象而不是具体 pub ...

  3. less命令查看文件时的常用操作

    下键或者回车:往下一行 D:往下半页 空格和f:往下一页 上键:往上一行 B:往上一页 shift+G:直接切到末尾 ?+搜索条件:从下往上搜索 /+搜索条件:从上往下搜索

  4. coreseek/sphinx中的匹配模式

    所谓匹配模式就是用户怎样依据keyword在索引库中查找相关的记录. SPH_MATCH_ALL, 匹配全部查询分词(默认模式); 如"手机配件".不匹配 "我有一部手机 ...

  5. 2018-2019-2 网络对抗技术 20165236 Exp6 信息搜集与漏洞扫描

    2018-2019-2 网络对抗技术 20165236 Exp6 信息搜集与漏洞扫描 一.实验内容 1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 ...

  6. JavaScript基本概念

    JavaScript概念:JavaScript是一个弱类型语言,而且不要进行编译,是解释性语言.JavaScript最初是为了处理一些相较简单的数据验证,从而减少客户端与服务器端的通信提升效率,发展至 ...

  7. Azure基础(二)- 核心云服务 - Azure简介

    Azure fundamentals - Core Cloud Services - Introduction to Azure Learn what Microsoft Azure is and h ...

  8. svg合并

    假如页面有多个svg图标要加载,多次加载不利,可将多个svg合并为一个加载 如下有两个svg <svg xmlns="http://www.w3.org/2000/svg" ...

  9. hightopo学习之旅一 -- 节点动画

    参照官网 动画手册 1.引入所需HT文件 <script src="plugins/ht/core/ht.js"></script> <script ...

  10. std::vector<bool> 在 auto 推断下的返回值是 bool & 引用

    转自: https://www.cnblogs.com/hustxujinkang/p/5218148.html //////////// std::vector<bool> featur ...