使用方式:
設(shè)置的標(biāo)題
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字體大小顯示不一致孙技,如下圖所示:
image.png
解決(分析TabLayout源代碼):
根據(jù)UI顯示的問題,我們首先想到的是字體大小設(shè)置的問題潦闲,通過TabLayout源代碼我們分析出在TabView.onMeasure方法中進行Tab-Text字體大小的設(shè)置,關(guān)鍵代碼如下
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
/* 這里是關(guān)鍵迫皱,當(dāng)TextView顯示多行時歉闰,textSize會被調(diào)整為mTabTextMultiLineSize,
* 而mTabTextMultiLineSize是在構(gòu)造函數(shù)中設(shè)置的大小
* mTabTextMultiLineSize = res.getDimensionPixelSize(R.dimen.design_tab_text_size_2line)
* 通過調(diào)試驗證卓起,核心內(nèi)參的大小確實被設(shè)置為了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);
}
}
}
}
那么問題來了和敬,<核心內(nèi)參>為什么顯示成多行了呢,通過調(diào)試發(fā)現(xiàn)既绩,TabView的寬度是大于<核心內(nèi)參>字體的寬度的概龄,而TabView內(nèi)TextView的寬度小于<核心內(nèi)參>字體的寬度,問題的關(guān)鍵就在這里饲握,TabView水平方向被設(shè)置了padding私杜,可是我并沒有設(shè)置mTabPaddingStart和mTabPaddingEnd呀蚕键,但是我們設(shè)置了style,在使用的style-StockTabLayout的parent中發(fā)現(xiàn)mTabPaddingStart衰粹,mTabPaddingEnd都被賦值為12dp锣光,所以才會導(dǎo)致這一問題,我們把mTabPaddingStart和mTabPaddingEnd設(shè)置為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>