遇到问题
项目中使用XTabLayout+ViewPager 实现tab页切换的功能,正常的使用肯定没啥问题,XTabLayout已经给我们封装了很丰富的方法,直接可以在xml中设置样式。包括滑动样式、分割线、选中标题颜色、字体大小等等
详细API可移步github
地址
遇到的问题是选中标题设置字体过大时,标题包含4个字和以上的就会换行,然后就是字数少的一行,字数多的两行,样式显示相当尴尬。
然后这里记录一下自己的填坑之路,最后结果其实非常简单,着急的朋友可以直接跳到最后
XML使用
1 | <com.androidkun.xtablayout.XTabLayout |
属性常用的就上边这些,其中
1 | app:xTabTextSize="14sp" |
表示未选中标题字体大小
1 | app:xTabSelectedTextSize="17sp" |
表示选中以后标题大小
可以看到选中以后标题比未选中的大,所以当tab滑到字数多一点的标签页时,就会换行。效果可以自行想象
解决思路
- 首先先去找API里有没有设置单行的方法,结果没找到
- 看源码换行原因
发现标签页的TabView 里设置了一个默认最大行数是2所以找的了换行的罪魁祸首就是,textview设置的默认最大行数为2行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class 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;
}
找到了位置,我们就去想是不是可以通过反射设置默认行数禁止换行
上手撸其中拿到TabView到代码参考如下1
2
3
4
5
6
7
8
9
10
11
12val 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运行看下效果,换行问题解决了,但是显示了三个字然后后边加…1
2
3
4
5
6
7
8
9
10
11public 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
找到源码包含到资源文件果然是尴尬,然后去想设置布局中的TextView默认宽度加宽一点好了,就不会占满出现…了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"/>
xml中找属性发现了xTabPaddingStart 和 xTabPaddingEnd很好,一边来上-5dp在看效果,完美解决1
2app:xTabPaddingStart="-5dp"
app:xTabPaddingEnd="-5dp"最后方案
实现完了以后又回过去复盘了一下,既然设置-5dp加宽了tab标签的宽度,之前换行、省略号那些的又都是因为宽度不够导致的,那么现在是不是可以不设置行数那些的一堆。验证一下把反射的代码注掉,只留padding,运行一下,果然可以。。。
乖乖的把反射代码删掉,整了半天白搞。 - 所以最后的方法还是在xml中添加两个属性*
1
2app:xTabPaddingStart="-5dp"
app:xTabPaddingEnd="-5dp"