最近写一个项目的时候用到了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. 根据数据库表结构生成java类

    import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWrit ...

  2. bzoj2734【HNOI2012】集合选数

    2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 831  Solved: 487 [Submit][Stat ...

  3. JavaScript常用的api

    打印日志 console.log 类型判断 第一种方式var type = Object.prototype.toString.call(list);console.log(type);第二种方式ty ...

  4. HD-ACM算法专攻系列(12)——Integer Inquiry

    问题描述: 源码: import java.math.BigInteger; import java.util.*; public class Main { //主函数 public static v ...

  5. if switch

    一.基本if结构: 1.语法:if (条件){ 代码块 } 2.执行顺序:先判断条件,条件成立则行{}内的代码,不成立则跳出if结构快既不执行{}内的代码. 3.什么情况下要用基本if选择结构:当需要 ...

  6. SpringBoot学习笔记(15)----SpringBoot使用Druid

    直接访问Druid官网wiki,有详细教程,地址如下: SpringBoot支持Druid地址:https://github.com/alibaba/druid/tree/master/druid-s ...

  7. map、栈————下一个更大的元素(待定,栈解法学习中)

    方法一 先遍历nums2,将每个元素后面第一个大的元素一起存入到map中,然后在遍历nums1,在map中找到. class Solution { public: vector<int> ...

  8. [AHOI2013]差异 后缀自动机_Parent树

    题中要求: $\sum_{1\leqslant i < j \leq n } Len(T_{i}) +Len(T_{j})-2LCP(T_{i},T_{j})$ 公式左边的部分很好求,是一个常量 ...

  9. Github README.md中添加图片

    1.先把图片上传到你的项目中:然后在github网站上按路径打开图片,如下打开的图片链接: 2.复制图片的地址 3.然后在README.md写上: ![这里随便写文字](你刚复制的图片路径) 注意  ...

  10. MYSQL锁表问题的解决方法

    本文实例讲述了MYSQL锁表问题的解决方法.分享给大家供大家参考,具体如下: 很多时候!一不小心就锁表!这里讲解决锁表终极方法! 案例一 mysql>show processlist; 参看sq ...