TabLayout中Indicator的样式修改
最近写一个项目的时候用到了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的样式修改的更多相关文章
- 解决vue中element组件样式修改无效
vue中element组件样式修改无效 <style> .detail{ .el-input__inner { height: 48px; } } </style> 直接写st ...
- a 标签中 title 属性样式修改
无文字描述,直接上测试页,看效果. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- Android中EditText样式修改 聚焦光标、背景
在Android开发中,根据项目的需求,需要定制一些特殊的样式,例如:使用EditText时,聚焦时的背景及光标图片使用自定义而非android系统默认的.这两天,在项目中涉及此需求,现记录如下: 首 ...
- HTML5中 audio标签的样式修改
由于html5的流行,现在移动端大多数的需求都可以使用audio来播放音频,但您可能只是需要很简单的播放/停止效果,但不同的浏览器上的audio样式却不尽人意,那么要怎么改变这个样式呢,其实它的原理比 ...
- 修改bootstrap-table中的分页样式
使用bootstrap-table时,使用$("")选择器没办法选中下方的分页button按钮,可能跟它是动态生成的有关吧. 最终找到与之对应的js(bootstrap-table ...
- vue中Element-ui样式修改
下拉框(el-dropdown) // hover 下拉框的hover效果 .el-dropdown-menu__item:focus, .el-dropdown-menu__item:not(.is ...
- ExtJS控件样式修改及美化
Extjs项目对富客户端开发提供了强有力的支持,甚至改变了前端的开发方式,使得开发变得更加趋向于“面向组件”.对界面的美化而言,也是根本性的改变.普通的网页美工面对extjs项目根本无法下手,需要脚本 ...
- 在网页中插入CSS样式表的几种方法
1. 链入外部样式表 链入外部样式表是把样式表保存为一个样式表文件,然后在页面中用<link>标记链接到这个样式表文件,这个<link>标记必须放到页面的<head> ...
- 帝国cms 列表页分页样式修改美化【2】
上一篇(帝国cms 列表页分页样式修改美化[1])中我们已经对分页说了一个大概,下面我们就自己动手弄一个分页把: 第一步:进入帝国cms后台,点击系统设置->系统参数设置->信息设置:里面 ...
随机推荐
- java.lang.ClassNotFoundException: org.jaxen.JaxenException
java.lang.ClassNotFoundException: org.jaxen.JaxenException java.lang.ClassNotFoundException: org.jax ...
- HBase基本数据操作具体解释
引言 本文档參考最新(截止2014年7月16日)的官方Ref Guide.Developer API编写. 全部代码均基于"hbase 0.96.2-hadoop2"版本号编写.均 ...
- CoreData的介绍和使用
一.CoreData是什么? CoreData是iOS SDK里的一个很强大的框架,允许程序员以面向对象的方式存储和管理数据.使用CoreData框架,程序员可以轻松有效地通过面向对象的接口管理数据 ...
- CentOS7安装EPEL的两种方式
转自:http://www.mamicode.com/info-detail-1671603.html epel是社区强烈打造的免费开源发行软件包版本库. EPEL,即Extra Packages f ...
- JAXB xml与javaBean的转换
转自:https://blog.csdn.net/lydong_/article/details/79812626 `1. 1.不认识到犯错,然后得到永久的教训. 也不是所谓的教训吧,真正的教训来自于 ...
- [codeforces 852 D] Exploration Plan 解题报告 (二分+最大匹配)
题目链接:http://codeforces.com/problemset/problem/852/D 题目大意: 有V个点,N个队伍,E条边,经过每条边有个时间,告诉你初始N个队伍的位置,求至少有K ...
- (三)Fegin声明式服务调用
上一篇,讲了SpringClound中的消费者采用Ribbon+Rest来实现,这回我们用组件Feign来实现服务的消费者,Fegin中也是默认集成了Ribbon的;和Eureka结合也能实现负载均衡 ...
- xBIM 基础01 简介
系列目录 [已更新最新开发文章,点击查看详细] 一.xBIM 简介 BIM(Building Information Modelling)建筑信息模型,xBIM(eXtensible Buil ...
- sicily 1002 Anti-prime Sequences
debug了好久..各种犯错..按照某个学长的思路,终于AC了.. #include <iostream> #include <cstring> using namespace ...
- Kettle的概念学习系列之Kettle是什么?(一)
不多说,直接上干货! Kettle是什么? Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,绿色无需安装,数据抽取高效稳定. Kettle 中文 ...