使用方式:
设置的标题
List<String> titleList= Arrays.asList("问股","诊股","核心题材", "公告","研报");
xml布局:
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
style="@style/StockTabLayout"
android:layout_width="match_parent"
android:layout_height="46dp" />
style样式:
<style name="StockTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">@style/StockTextAppearance</item>
<item name="tabSelectedTextColor">@color/theme_color</item>
<item name="tabIndicatorColor">@color/theme_color</item>
<item name="tabIndicatorHeight">1dp</item>
<item name="tabMode">fixed</item>
</style>
<style name="StockTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/black</item>
</style>
问题:TabLayout的Tab字体大小显示不一致,如下图所示:
解决(分析TabLayout源代码):
根据UI显示的问题,我们首先想到的是字体大小设置的问题,通过TabLayout源代码我们分析出在TabView.onMeasure方法中进行Tab-Text字体大小的设置,关键代码如下
public void onMeasure(final int origWidthMeasureSpec, final int origHeightMeasureSpec) {
//...省略代码
// We need to switch the text size based on whether the text is spanning 2 lines or not
if (mTextView != null) {
final Resources res = getResources();
float textSize = mTabTextSize;
int maxLines = mDefaultMaxLines;
if (mIconView != null && mIconView.getVisibility() == VISIBLE) {
// If the icon view is being displayed, we limit the text to 1 line
maxLines = 1;
} else if (mTextView != null && mTextView.getLineCount() > 1) {
// Otherwise when we have text which wraps we reduce the text size
/* 这里是关键,当TextView显示多行时,textSize会被调整为mTabTextMultiLineSize,
* 而mTabTextMultiLineSize是在构造函数中设置的大小
* mTabTextMultiLineSize = res.getDimensionPixelSize(R.dimen.design_tab_text_size_2line)
* 通过调试验证,核心内参的大小确实被设置为了mTabTextMultiLineSize的大小
*/
textSize = mTabTextMultiLineSize;
}
final float curTextSize = mTextView.getTextSize();
final int curLineCount = mTextView.getLineCount();
final int curMaxLines = TextViewCompat.getMaxLines(mTextView);
if (textSize != curTextSize || (curMaxLines >= 0 && maxLines != curMaxLines)) {
// We've got a new text size and/or max lines...
boolean updateTextView = true;
if (mMode == MODE_FIXED && textSize > curTextSize && curLineCount == 1) {
// If we're in fixed mode, going up in text size and currently have 1 line
// then it's very easy to get into an infinite recursion.
// To combat that we check to see if the change in text size
// will cause a line count change. If so, abort the size change and stick
// to the smaller size.
final Layout layout = mTextView.getLayout();
if (layout == null || approximateLineWidth(layout, 0, textSize)
> getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) {
updateTextView = false;
}
}
if (updateTextView) {
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
mTextView.setMaxLines(maxLines);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
}
那么问题来了,<核心内参>为什么显示成多行了呢,通过调试发现,TabView的宽度是大于<核心内参>字体的宽度的,而TabView内TextView的宽度小于<核心内参>字体的宽度,问题的关键就在这里,TabView水平方向被设置了padding,可是我并没有设置mTabPaddingStart和mTabPaddingEnd呀,但是我们设置了style,在使用的style-StockTabLayout的parent中发现mTabPaddingStart,mTabPaddingEnd都被赋值为12dp,所以才会导致这一问题,我们把mTabPaddingStart和mTabPaddingEnd设置为0dp就能正常显示了。
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabMaxWidth">@dimen/design_tab_max_width</item>
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">?attr/selectableItemBackground</item>
<item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>