SpannableStringBuilder可以用来实现富文本样式。
TextAppearanceSpan是系统提供的用来修改文本简单样式:
- 设置不同的文字大小
- 设置不同的文字颜色
- 设置文字的字体
- 设置文字粗体
- 超链接颜色
fun testSpan() {
var builder = SpannableStringBuilder()
var price = "10,837"
var note = "当前价"
builder.append("¥")
builder.append("${price} ")
builder.append(note)
//默认字体,粗体,文字大小:60,红色
var yuanSpan = TextAppearanceSpan(
null, Typeface.BOLD, 60,
ColorStateList.valueOf(resources.getColor(R.color._C6100E)), null
)
builder.setSpan(yuanSpan, 0, 1, SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE)
//默认字体,粗体,文字大小:80,红色
var priceSpan = TextAppearanceSpan(
null, Typeface.BOLD, 80,
ColorStateList.valueOf(resources.getColor(R.color._C6100E)), null
)
builder.setSpan(
priceSpan,
1,
price.length + 1,
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
)
//serif字体,正常,文字大小:60,灰色
var noteSpan = TextAppearanceSpan(
"sans", Typeface.NORMAL, 60,
ColorStateList.valueOf(resources.getColor(R.color._888888)), null
)
builder.setSpan(
noteSpan,
builder.length - note.length,
builder.length,
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
)
findViewById(R.id.tv_app).setText(builder)
}
效果如图:
!
TextAppearanceSpan支持的属性,可以从源码中获得:
/**
* Uses the specified TextAppearance resource to determine the
* text appearance, and the specified text color resource
* to determine the color. The appearance
should be,
* for example, android.R.style.TextAppearance_Small
,
* and the colorList
should be, for example,
* android.R.styleable.Theme_textColorPrimary
.
*/
public TextAppearanceSpan(Context context, int appearance, int colorList) {
ColorStateList textColor;
TypedArray a =
context.obtainStyledAttributes(appearance,
com.android.internal.R.styleable.TextAppearance);
//字体颜色
textColor = a.getColorStateList(com.android.internal.R.styleable.
TextAppearance_textColor);
//超链接颜色
mTextColorLink = a.getColorStateList(com.android.internal.R.styleable.
TextAppearance_textColorLink);
//字体大小
mTextSize = a.getDimensionPixelSize(com.android.internal.R.styleable.
TextAppearance_textSize, -1);
//风格:粗体、斜体、正常
mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0);
//字体
if (!context.isRestricted() && context.canLoadUnsafeResources()) {
mTypeface = a.getFont(com.android.internal.R.styleable.TextAppearance_fontFamily);
} else {
mTypeface = null;
}
if (mTypeface != null) {
mFamilyName = null;
} else {
String family = a.getString(com.android.internal.R.styleable.TextAppearance_fontFamily);
if (family != null) {
mFamilyName = family;
} else {
int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0);
switch (tf) {
case 1:
mFamilyName = "sans";
break;
case 2:
mFamilyName = "serif";
break;
case 3:
mFamilyName = "monospace";
break;
default:
mFamilyName = null;
break;
}
}
}
mTextFontWeight = a.getInt(com.android.internal.R.styleable
.TextAppearance_textFontWeight, -1);
final String localeString = a.getString(com.android.internal.R.styleable
.TextAppearance_textLocale);
if (localeString != null) {
LocaleList localeList = LocaleList.forLanguageTags(localeString);
if (!localeList.isEmpty()) {
mTextLocales = localeList;
} else {
mTextLocales = null;
}
} else {
mTextLocales = null;
}
//文字投影
mShadowRadius = a.getFloat(com.android.internal.R.styleable
.TextAppearance_shadowRadius, 0.0f);
mShadowDx = a.getFloat(com.android.internal.R.styleable
.TextAppearance_shadowDx, 0.0f);
mShadowDy = a.getFloat(com.android.internal.R.styleable
.TextAppearance_shadowDy, 0.0f);
mShadowColor = a.getInt(com.android.internal.R.styleable
.TextAppearance_shadowColor, 0);
mHasElegantTextHeight = a.hasValue(com.android.internal.R.styleable
.TextAppearance_elegantTextHeight);
mElegantTextHeight = a.getBoolean(com.android.internal.R.styleable
.TextAppearance_elegantTextHeight, false);
mHasLetterSpacing = a.hasValue(com.android.internal.R.styleable
.TextAppearance_letterSpacing);
mLetterSpacing = a.getFloat(com.android.internal.R.styleable
.TextAppearance_letterSpacing, 0.0f);
mFontFeatureSettings = a.getString(com.android.internal.R.styleable
.TextAppearance_fontFeatureSettings);
mFontVariationSettings = a.getString(com.android.internal.R.styleable
.TextAppearance_fontVariationSettings);
a.recycle();
if (colorList >= 0) {
a = context.obtainStyledAttributes(com.android.internal.R.style.Theme,
com.android.internal.R.styleable.Theme);
textColor = a.getColorStateList(colorList);
a.recycle();
}
mTextColor = textColor;
}