XTabLayout修改选中标题大小且不换行

遇到问题

项目中使用XTabLayout+ViewPager 实现tab页切换的功能,正常的使用肯定没啥问题,XTabLayout已经给我们封装了很丰富的方法,直接可以在xml中设置样式。包括滑动样式、分割线、选中标题颜色、字体大小等等
详细API可移步github
地址
遇到的问题是选中标题设置字体过大时,标题包含4个字和以上的就会换行,然后就是字数少的一行,字数多的两行,样式显示相当尴尬。
然后这里记录一下自己的填坑之路,最后结果其实非常简单,着急的朋友可以直接跳到最后

XML使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<com.androidkun.xtablayout.XTabLayout
android:id="@+id/xl_live_list"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
app:xTabDividerGravity="bottom"
app:xTabIndicatorColor="@color/app_blue"
app:xTabIndicatorHeight="2dp"
app:xTabIndicatorWidth="15dp"
app:xTabMode="scrollable"
app:xTabSelectedTextColor="@color/app_blue"
app:xTabSelectedBackgroundColor="@color/white"
app:xTabSelectedTextSize="17sp"
app:xTabTextColor="@color/app_textcolor2"
app:xTabTextSize="14sp"
/>

属性常用的就上边这些,其中

1
app:xTabTextSize="14sp"

表示未选中标题字体大小

1
app:xTabSelectedTextSize="17sp"

表示选中以后标题大小
可以看到选中以后标题比未选中的大,所以当tab滑到字数多一点的标签页时,就会换行。效果可以自行想象

解决思路

  • 首先先去找API里有没有设置单行的方法,结果没找到
  • 看源码换行原因
    发现标签页的TabView 里设置了一个默认最大行数是2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class TabView extends LinearLayout implements OnLongClickListener {
    private XTabLayout.Tab mTab; //对外提供Tab标签
    private TextView mTextView; // 标签内TextView 我们要处理的对象
    private ImageView mIconView;
    private View mCustomView;
    private TextView mCustomTextView;
    private ImageView mCustomIconView;
    private int mDefaultMaxLines = 2; // 默认最大行数
    ...
    省略
    if (this.mTextView != null) {
    Resources res = this.getResources();
    float textSize = XTabLayout.this.mTabTextSize;
    int maxLines = this.mDefaultMaxLines; // 设置最大行数
    if (this.mIconView != null && this.mIconView.getVisibility() == 0) {
    maxLines = 1;
    } else if (this.mTextView != null && this.mTextView.getLineCount() > 1) {
    textSize = XTabLayout.this.mTabTextMultiLineSize;
    }
    所以找的了换行的罪魁祸首就是,textview设置的默认最大行数为2行
    找到了位置,我们就去想是不是可以通过反射设置默认行数禁止换行
    上手撸
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    val newTab = rootview.xl_live_add_course.newTab() as XTabLayout.Tab //创建标签页
    val field = XTabLayout.Tab::class.java.getDeclaredField("mView")//拿到TabView
    val tabView = Class.forName("com.liqiang365.widget.xtablayout.XTabLayout${'$'}TabView")// 反射创建内部类的TabView
    val defaultMaxLines = tabView.getDeclaredField("mDefaultMaxLines")//拿到默认最大行数
    field.isAccessible = true
    defaultMaxLines.isAccessible = true
    val xTableView = field.get(newTab)
    val tvField = tabView.getDeclaredField("mTextView")//拿到TextView
    tvField.isAccessible = true
    val mTextView = tvField.get(xTableView) as TextView
    defaultMaxLines.set(xTableView, 1) //设置最大行数1
    rootview.xl_live_add_course.addTab(newTab.setText(bean.name))// 添加tab
    其中拿到TabView到代码参考如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static final class Tab {
    public static final int INVALID_POSITION = -1;
    private Object mTag;
    private Drawable mIcon;
    private CharSequence mText;
    private CharSequence mContentDesc;
    private int mPosition;
    private View mCustomView;
    private XTabLayout mParent;
    private XTabLayout.TabView mView;
    ...
    运行看下效果,换行问题解决了,但是显示了三个字然后后边加…
    晕,肯定是位置不够肯定是设置了ellipsize=end
    找到源码包含到资源文件果然是
    1
    2
    3
    4
    5
    6
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:gravity="center"
    android:maxLines="2"/>
    尴尬,然后去想设置布局中的TextView默认宽度加宽一点好了,就不会占满出现…了
    xml中找属性发现了xTabPaddingStart 和 xTabPaddingEnd很好,一边来上-5dp
    1
    2
    app:xTabPaddingStart="-5dp"
    app:xTabPaddingEnd="-5dp"
    在看效果,完美解决

    最后方案

    实现完了以后又回过去复盘了一下,既然设置-5dp加宽了tab标签的宽度,之前换行、省略号那些的又都是因为宽度不够导致的,那么现在是不是可以不设置行数那些的一堆。验证一下把反射的代码注掉,只留padding,运行一下,果然可以。。。
    乖乖的把反射代码删掉,整了半天白搞。
  • 所以最后的方法还是在xml中添加两个属性*
    1
    2
    app:xTabPaddingStart="-5dp"
    app:xTabPaddingEnd="-5dp"