单个TextView 要实现复杂的富文本效果,可借助SpannableString实现。
主要实现方法 SpannableString.setSpan(Object what, int start, int end, int flags)
start 指定span开始位置。包括该位置。
end 指定span结束位置,不包括该位置。
// 背景色
private void setBackgroundColor() {
SpannableString spannableString = new SpannableString("测试用的文本修改字体背景颜色");
//BackgroundColorSpan backSpan = new BackgroundColorSpan(Color.parseColor("#0000ff"));
BackgroundColorSpan backSpan = new BackgroundColorSpan(Color.RED);
//BackgroundColorSpan backSpan = new BackgroundColorSpan(CommonUtils.getColor(TestActivity.this, R.color.colorAccent));
spannableString.setSpan(backSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 前景色
private void setForegroundColor() {
SpannableString spannableString = new SpannableString("测试用的文本修改字体前景颜色");
//ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#ff0000"));
//ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.BLUE);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(CommonUtils.getColor(TestActivity.this, R.color.colorAccent));
spannableString.setSpan(colorSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv02.setText(spannableString);
}
// 修饰效果-模糊
private void setBlurMaskFilter() {
// 注意:使用 MaskFilterSpan 修饰效果,需要关闭硬件加速,不然没有效果出来。
// 在AndroidManifest.xml中对应的activity设置android:hardwareAccelerated="false"
// 参看:https://stackoverflow.com/questions/46089196/how-to-using-android-spannablestring-and-maskfilterspan-to-blur-some-text-from-t
SpannableString spannableString = new SpannableString("测试用的文本修饰效果之模糊测试");
MaskFilterSpan blurSpan0 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
MaskFilterSpan blurSpan4 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.SOLID));
MaskFilterSpan blurSpan8 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.OUTER));
MaskFilterSpan blurSpan12 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.INNER));
spannableString.setSpan(blurSpan0, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
spannableString.setSpan(blurSpan4, 4, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
spannableString.setSpan(blurSpan8, 8, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
spannableString.setSpan(blurSpan12, 12, 14, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 删除线
private void setStrikethroughSpan() {
SpannableString spannableString = new SpannableString("测试用的文本加上删除线");
StrikethroughSpan backSpan = new StrikethroughSpan();
spannableString.setSpan(backSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 下划线
private void setUnderlineSpan() {
SpannableString spannableString = new SpannableString("测试用的文本加上下划线");
UnderlineSpan span = new UnderlineSpan();
spannableString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 字体大小(相对大小)
private void setRelativeSizeSpan() {
SpannableString spannableString = new SpannableString("测试用的文本图片字体大小(相对大小)");
RelativeSizeSpan span = new RelativeSizeSpan(1.5f);
spannableString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 基于x轴缩放
private void setScaleXSpan() {
SpannableString spannableString = new SpannableString("测试用的文本基于x轴缩放");
ScaleXSpan span = new ScaleXSpan(0.5f);
spannableString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
SpannableString spannableString2 = new SpannableString("测试用的文本基于x轴缩放");
for (int i = 0; i < spannableString2.length(); i++) {
float proportion = (float) (0.5f + (0.1 * i));
spannableString2.setSpan(new ScaleXSpan(proportion), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tv02.setText(spannableString2);
}
// 加粗斜体
private void setStyleSpan() {
SpannableString spannableString = new SpannableString("测试加粗测试斜体测试加粗斜体");
// 加粗
StyleSpan span = new StyleSpan(Typeface.BOLD);
spannableString.setSpan(span, 2, 4, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
// 斜体
StyleSpan span2 = new StyleSpan(Typeface.ITALIC);
spannableString.setSpan(span2, 6, 8, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
// 加粗斜体
StyleSpan span3 = new StyleSpan(Typeface.BOLD_ITALIC);
spannableString.setSpan(span3, 10, 14, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 上标下标(数学公式会用到)
private void setSubscriptSpan() {
SpannableString spannableString = new SpannableString("测试用的文本2018");
SuperscriptSpan span = new SuperscriptSpan();
spannableString.setSpan(span, 6, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
SpannableString spannableString2 = new SpannableString("测试用的文本2018");
SubscriptSpan span2 = new SubscriptSpan();
spannableString2.setSpan(span2, 6, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv02.setText(spannableString2);
}
// 文本外貌(包括字体、大小、样式和颜色)
private void setTextAppearanceSpan() {
SpannableString sstr = new SpannableString("测试文本修改字体修改大小修改样式修改颜色");
ColorStateList csl = getResources().getColorStateList(R.color.red);
TextAppearanceSpan span = new TextAppearanceSpan("default", android.graphics.Typeface.BOLD, 20, csl, null);
sstr.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv01.setText(sstr);
}
// 设置字体
private void setTypefaceSpan() {
SpannableString spannableString = new SpannableString("测试用的文本");
// "monospace", "serif", and "sans-serif".
TypefaceSpan span = new TypefaceSpan("serif");
spannableString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
}
// 设置链接
private void setURLSpan() {
SpannableString spannableString = new SpannableString("测试用的文本这是链接地址");
spannableString.setSpan(new URLSpan("https://baidu.com"), 0, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
// 执行动作需要设置MovementMethod
tv01.setMovementMethod(LinkMovementMethod.getInstance());
}
// 设置点击事件
private void setClickableSpan() {
SpannableString spannableString = new SpannableString("测试用的文本点击事件");
ClickableSpan span = new ClickableSpan() {
@Override
public void onClick(View widget) {
showToast("点一点");
}
};
spannableString.setSpan(span, spannableString.length() - 4, spannableString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
tv01.setText(spannableString);
// 执行动作需要设置MovementMethod
tv01.setMovementMethod(LinkMovementMethod.getInstance());
}
参看:
https://blog.csdn.net/fengyuzhengfan/article/details/38459299
https://www.jianshu.com/p/f004300c6920