前言

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

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

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

先上图。

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

java类

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox; import java.util.ArrayList;
import java.util.List; import butterknife.BindView;
import butterknife.ButterKnife; public class MainActivity extends AppCompatActivity {
@BindView(R.id.vp_all)
ViewPager vpAll;
@BindView(R.id.tab_custom)
TabLayout tabCustom; //存放自定义tab标签的列表
List<View> customTabList = new ArrayList<>();
//存放对应tab标签的fragment页面
List<PageFragment> fgList = new ArrayList<>();
//选中的自定义标签,标记器。默认选中第一个。标记位是0;
int indicator = 0; ViewPagerAdapter pagerAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);//此处是用的是butterKnife框架,等同于findviewbyid获取各个控件。
initTabCustomAndViewPager();
initListener();
} /**
* 初始化tab标签和viewpager内容。
*/
private void initTabCustomAndViewPager() {
//初始化10个自定义tab标签
for (int i = 0; i < 10; i++) {
final View tabView = getCustomTabView(this, "自定义" + i);
customTabList.add(tabView);
if (i==0){
//设置默认第一个选中效果
((CheckBox) tabView.findViewById(R.id.cb_name)).setChecked(true);
tabView.findViewById(R.id.cb_slide).setVisibility(View.VISIBLE);
}
tabCustom.addTab(tabCustom.newTab().setCustomView(tabView));
}
//初始化10个fragment页面
for (int i = 0; i < 10; i++) {
fgList.add(PageFragment.newInstance("我是内容栏目" + i));
}
pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fgList);
vpAll.setAdapter(pagerAdapter);
} /**
* 将viewpager和tabLayout之间的滑动事件和点击事件关联起来。
* 此处不能使用tabLayout的setupWithViewPager()方法,否则会造成自定义view失效
*/
private void initListener() {
//添加关联接口,此处不能用自带的绑定方法,否则自定义view会失效
vpAll.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
} @Override
public void onPageSelected(int i) {
tabCustom.getTabAt(i).select();
} @Override
public void onPageScrollStateChanged(int i) {
}
});
tabCustom.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//viewpager联动
vpAll.setCurrentItem(tab.getPosition());
//将之前选中的tab标签,设置为未选中状态
View oldView = customTabList.get(indicator);
CheckBox oldCbName = (CheckBox) oldView.findViewById(R.id.cb_name);
View oldCbSlide = oldView.findViewById(R.id.cb_slide);
oldCbName.setChecked(false);
oldCbSlide.setVisibility(View.INVISIBLE);
//当前选中的tab标签,设置为选中状态。
indicator = tab.getPosition();
View newView = customTabList.get(indicator);
CheckBox newCbName = (CheckBox) newView.findViewById(R.id.cb_name);
View newCbSlide = newView.findViewById(R.id.cb_slide);
newCbName.setChecked(true);
newCbSlide.setVisibility(View.VISIBLE);
} @Override
public void onTabUnselected(TabLayout.Tab tab) {
} @Override
public void onTabReselected(TabLayout.Tab tab) {
}
}); } /**
* ViewPager的适配器。
*/
class ViewPagerAdapter extends FragmentPagerAdapter { List<PageFragment> fragmentList; public ViewPagerAdapter(FragmentManager fm, List<PageFragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
} @Override
public Fragment getItem(int position) {
return fragmentList.get(position);
} @Override
public int getCount() {
return fragmentList.size();
}
} /**
* 获取自定义Tab标签的显示的内容
*
* @param context
* @param
* @return
*/
public static View getCustomTabView(Context context, String text) {
View view = LayoutInflater.from(context).inflate(R.layout.item_custom_tab, null);
CheckBox tabText = (CheckBox) view.findViewById(R.id.cb_name);
tabText.setText(text);
return view;
}
}

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

布局文件

activity_main的布局文件

<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.tablayoutdemo.MainActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tab_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorHeight="0dp"
app:tabMode="scrollable"
/> <android.support.v4.view.ViewPager
android:id="@+id/vp_all"
android:layout_width="match_parent"
android:layout_height="match_parent" /> </LinearLayout>

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical"
android:gravity="center"
android:descendantFocusability="blocksDescendants">
<CheckBox
android:id="@+id/cb_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:text=""
android:textColor="@drawable/select_text_color"
android:textSize="15sp"
android:paddingTop="13dp"
android:ellipsize="end"
android:singleLine="true"
android:maxEms="5"
android:textStyle="bold"
android:paddingBottom="13dp"
android:clickable="false"
/>
<View
android:id="@+id/cb_slide"
android:layout_width="20dp"
android:layout_height="3dp"
android:visibility="invisible"
android:background="#ff4fbf86"/> </LinearLayout>

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

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#ff4fbf86" android:state_checked="true"/>
<item android:color="#BBBBBB" android:state_checked="false" />
</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. Express全系列教程之(四):获取Post参数的两种方式

    一.关于POST请求 post方法作为http请求很重要的一部分,几乎所有的网站都有用到它,与get不同,post请求更像是在服务器上做修改操作,它一般用于数据资源的更新.相比于get请求,post所 ...

  2. 异想-天开 python---while、for、if-else 循环学习

    for循环: for i in range(10): # i循环10次 print('------',i) for j in range(10): print(j) if j > 2 : bre ...

  3. 精心调制的Bash主题分享

    第一个是米色背景, 一样遵守蓝色为目录的习惯, 字体为浅灰色,代码和终端看起来相对比较清晰 第二个则是 深海蓝的背景风格,字体都选择饱和度较高的颜色,如下图 终端 配置方法,这里以 mintty 也就 ...

  4. 数电基础之《OC门》

    OC门,又称集电极开路门,Open Collector.   为什么引入OC门?实际使用中,有时需要两个或两个以上与非门的输出端连接在同一条导线上,将这些与非门上的数据(状态电平)用同一条导线输送出去 ...

  5. 806. Number of Lines To Write String

    806. Number of Lines To Write String 整体思路: 先得到一个res = {a : 80 , b : 10, c : 20.....的key-value对象}(目的是 ...

  6. levmar : Levenberg-Marquardt库编译

    levmar : Levenberg-Marquardt 是非线性优化的一个库 1.使用CMake生成sln项目,编译 clapack库 在levmar工程中,打开misc.c文件,在最开始添加#in ...

  7. composer学习之路01

    以前对composer还是的理解很模糊,直到最近看一些资料,稍微有了一些浅显的了解. /* composer依赖包管理工具,如果一个项目是windows操作系统,那么composer就是360,他可以 ...

  8. Flask性能优化对比

    基于Flask的网关:Flask,Uwsgi,Gevent,Gunicorn(gevent),Tornado,Twisted !/usr/bin/python -- coding:utf-8 -- 美 ...

  9. NGUI之实现连连看小游戏

    一,部分游戏规则如下: 二,代码如下: 1. 游戏逻辑核心代码 using System.Collections.Generic; using UnityEngine; namespace Modul ...

  10. mysql添加用户,授权,刷新权限

    创建用户 CREATE USER 'test'@'localhost' IDENTIFIED BY '123456'; 赋权 GRANT ALL PRIVILEGES ON *.* TO 'test' ...