最近写一个项目的时候用到了TabLayout,其中Indicator只是固定的一条横线,样式只能修改Color和Height,没有办法改变形状和宽度等其他信息。

经过查看TabLayout类的源码,发现了其存在一个私有的内部类SlidingTabStrip,这个类继承自LinearLayout,而Indicator就是在此类中进行绘制的。

@Override
public void draw(Canvas canvas) {
super.draw(canvas); // Thick colored underline below the current selection
if (mIndicatorLeft >= && mIndicatorRight > mIndicatorLeft) {
canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
}
}

在它的onDraw方法中,可以看到绘制的是一个Rect,并且宽度是根据mIndicatorLeft和mIndicatorRight这两个成员变量来决定的,再往上看会发现这两个变量的值是实时计算出来的。

rivate void updateIndicatorPosition() {
final View selectedTitle = getChildAt(mSelectedPosition);
int left, right; if (selectedTitle != null && selectedTitle.getWidth() > ) {
left = selectedTitle.getLeft();
right = selectedTitle.getRight(); if (mSelectionOffset > 0f && mSelectedPosition < getChildCount() - ) {
// Draw the selection partway between the tabs
View nextTitle = getChildAt(mSelectedPosition + );
left = (int) (mSelectionOffset * nextTitle.getLeft() +
(1.0f - mSelectionOffset) * left);
right = (int) (mSelectionOffset * nextTitle.getRight() +
(1.0f - mSelectionOffset) * right);
}
} else {
left = right = -;
} setIndicatorPosition(left, right);
} private void setIndicatorPosition(int left, int right) {
if (left != mIndicatorLeft || right != mIndicatorRight) {
// If the indicator's left/right has changed, invalidate
mIndicatorLeft = left;
mIndicatorRight = right;
ViewCompat.postInvalidateOnAnimation(this);
}
}

这里大概意思是根据当前选中的SlidingTabStrip的Child的宽度来得出mIndicatorLeft和mIndicatorRight的值,而这个Child我觉得其实就相当于Tab,这样一来如果想简单的修改一下Indicator的宽度,其实可以稍微给Child加点Margin就可以了。这个类和其对象在SlidingTabStrip都是私有的,可以通过反射的方式进行修改。

我的思路是,首先得到TabLayout的Class对象,然后得到私有成员变量mSlidingTabStrip的Field,通过Field得到值强转为LinearLayout,之后只需要遍历LinearLayout中所有的Child为其增加Margin即可,实现代码如下:

Class<?> tablayout = tl_main.getClass();
Field tabStrip = tablayout.getDeclaredField("mTabStrip");
tabStrip.setAccessible(true);
LinearLayout ll_tab= (LinearLayout) tabStrip.get(tl_main);
for (int i = ; i < ll_tab.getChildCount(); i++) {
View child = ll_tab.getChildAt(i);
child.setPadding(,,,);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(, LinearLayout.LayoutParams.MATCH_PARENT,);
params.setMarginStart(DensityUtil.dip2px(20f));
params.setMarginEnd(DensityUtil.dip2px(20f));
child.setLayoutParams(params);
child.invalidate();
}

最后得到效果如图:

 

至于Indicator的形状,因为在onDraw方法中绘制的是Rect,只靠反射是改动不了的,我觉得可以自定义一个类继承SlidingTabStrip重写其onDraw方法或者直接弃用TabLayout自带的Indicator,自己写一个IndicatorView将其和TabLayout放入FrameLayout,使IndicatorView响应TabLayout的Tab切换事件就好。

TabLayout中Indicator的样式修改的更多相关文章

  1. 解决vue中element组件样式修改无效

    vue中element组件样式修改无效 <style> .detail{ .el-input__inner { height: 48px; } } </style> 直接写st ...

  2. a 标签中 title 属性样式修改

    无文字描述,直接上测试页,看效果. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  3. Android中EditText样式修改 聚焦光标、背景

    在Android开发中,根据项目的需求,需要定制一些特殊的样式,例如:使用EditText时,聚焦时的背景及光标图片使用自定义而非android系统默认的.这两天,在项目中涉及此需求,现记录如下: 首 ...

  4. HTML5中 audio标签的样式修改

    由于html5的流行,现在移动端大多数的需求都可以使用audio来播放音频,但您可能只是需要很简单的播放/停止效果,但不同的浏览器上的audio样式却不尽人意,那么要怎么改变这个样式呢,其实它的原理比 ...

  5. 修改bootstrap-table中的分页样式

    使用bootstrap-table时,使用$("")选择器没办法选中下方的分页button按钮,可能跟它是动态生成的有关吧. 最终找到与之对应的js(bootstrap-table ...

  6. vue中Element-ui样式修改

    下拉框(el-dropdown) // hover 下拉框的hover效果 .el-dropdown-menu__item:focus, .el-dropdown-menu__item:not(.is ...

  7. ExtJS控件样式修改及美化

    Extjs项目对富客户端开发提供了强有力的支持,甚至改变了前端的开发方式,使得开发变得更加趋向于“面向组件”.对界面的美化而言,也是根本性的改变.普通的网页美工面对extjs项目根本无法下手,需要脚本 ...

  8. 在网页中插入CSS样式表的几种方法

    1. 链入外部样式表 链入外部样式表是把样式表保存为一个样式表文件,然后在页面中用<link>标记链接到这个样式表文件,这个<link>标记必须放到页面的<head> ...

  9. 帝国cms 列表页分页样式修改美化【2】

    上一篇(帝国cms 列表页分页样式修改美化[1])中我们已经对分页说了一个大概,下面我们就自己动手弄一个分页把: 第一步:进入帝国cms后台,点击系统设置->系统参数设置->信息设置:里面 ...

随机推荐

  1. Hive分区表与分桶

    分区表 在Hive Select查询中.通常会扫描整个表内容,会消耗非常多时间做不是必需的工作. 分区表指的是在创建表时,指定partition的分区空间. 分区语法 create table tab ...

  2. Hibernate中session回话的get方法和load方法的区别

    1.报错方式不同: 前提:获取的数据不存在 get方法会报异常:空指针异常 load方法会报异常:对象为找到异常,给定值没有行存在. 2.load方法 这种方式总是会返回一个代理而不是真正得去查询数据 ...

  3. Sobel算子及C++实现

    Sobel 算子是一个离散的一阶微分算子,用来计算图像灰度函数的近似梯度. 在空间域上Sobel算子很容易实现,执行速度快,对部分噪声具有平滑作用,还能够提供较为精确的边缘方向信息,缺点是边缘定位精度 ...

  4. Linux就该这么学 20181003(第三章管道符)

    参考链接https://www.linuxprobe.com/ 输入输出重定向 标准输入重定向STDIN 文件描述符0 默认键盘输入 标准输出重定向STOUT 文件描述符1 默认输出到屏幕 错误输出重 ...

  5. 整数翻转C++实现 java实现 leetcode系列(七)

    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: ...

  6. Visual Studio 2015 官方下载及密钥

    Microsoft Visual Studio(简称VS)是美国微软公司的开发工具包系列产品.Visual Studio 2015 是一个丰富的集成开发环境,可用于创建出色的 Windows.Andr ...

  7. android常用自动化测试框架

    目录: Monkey MonkeyRunner Instrumentation UiAutomator Espresso Selendroid Robotium Athrun Appium Monke ...

  8. jqGrid的editrules参数

    原文链接:http://blog.csdn.net/mengtianyalll/article/details/13502841 editrules    editrules是用来设置一些可用于可编辑 ...

  9. node.js连接数据库基本操作、封装数据库操作,输出到网页

    声明:以下代码测试通过,不同于直接的复制粘贴乱七八糟未测试的代码,完全可以用,最后会附上所有的代码和sql文件 首先建立表,建表语句如下: /* SQLyog Ultimate v12.08 (64 ...

  10. Servlet学习(一)——Servlet的生命周期、执行过程、配置

    1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过jav ...