一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
前言
在Android开发过程中,我们经常遇到显示多种风格的文本,比如部分加粗,部分变色,除了多个TextView拼接之外我们一般还有以下两种方式处理这类需求。
1.HtmlCompat
通过HtmlCompat.fromHtml()
方法我们很容易实现变颜色,加粗字体等需求,它有两个参数,第一个是带样式的字符串,含有html标签,第二个参数是解析字符串的一些规则flag,主要有以下取值:
@IntDef(value = {
FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH,
FROM_HTML_SEPARATOR_LINE_BREAK_HEADING,
FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM,
FROM_HTML_SEPARATOR_LINE_BREAK_LIST,
FROM_HTML_SEPARATOR_LINE_BREAK_DIV,
FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE,
FROM_HTML_OPTION_USE_CSS_COLORS,
FROM_HTML_MODE_COMPACT,
FROM_HTML_MODE_LEGACY
}, flag = true)
@RestrictTo(LIBRARY_GROUP_PREFIX)
@Retention(SOURCE)
@interface FromHtmlFlags {
}
FROM_HTML_SEPARATOR_LINE_BREAK_HEADING
:h1-h6标签中的文本将与其他文本用一个换行符分隔
FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH
自带换行
其他包含LINE_BREAK的flag也是处理各种标签换行的,比如li,ul等标签,下面将进行简单的使用
private fun formatSpanString(): Spanned {
val htmlStr2 = ("<span>" +
//大号字体-自带换行
"<h3><font color='#000000'>春江花月夜</font></h3>" +
//自带换行
"<p><font color='#90EE90'>春江潮水连海平,海上明月共潮生。</font></p>" +
//正常字体
"<font color='#FF00FF'>滟滟随波千万里,何处春江无月明!</font><br>" +
//加粗
"<strong><font color='#3CB371'>江流宛转绕芳甸,月照花林皆似霰;</font></strong><br>" +
//斜体
"<em><font color='#FF4500'>空里流霜不觉飞,汀上白沙看不见。</font></em><br>" +
//带有下划线
"<u><font color='#8B4513'>江天一色无纤尘,皎皎空中孤月轮。</font></u><br>" +
//加大字体
"<big><font color='#800080'>江畔何人初见月?江月何年初照人?</font></big><br>" +
"</span>")
return HtmlCompat.fromHtml(htmlStr2, HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH)
}
运行效果如下
2.SpannableString
SpannableString
可以通过setSpan
方法给字符串添加各种显示风格,而且非常方便指定设置的区间大小,在使用过程中如果要多次修改,一般使用SpannableStringBuilder。setSpan函数的原型为public void setSpan(Object what, int start, int end, int flags)
,其中what指定需要设置的样式,start和end为设置的区间,flag设置包不包含下标,有下面四种取值:
int SPAN_EXCLUSIVE_EXCLUSIVE = 33;
不包含start和endint SPAN_EXCLUSIVE_INCLUSIVE = 34;
不包含start,包含endint SPAN_INCLUSIVE_EXCLUSIVE = 17;
包含start,不包含endint SPAN_INCLUSIVE_INCLUSIVE = 18;
包含start和end 常用的Span如下
ForegroundColorSpan
ForegroundColorSpan用来设置前景色,可以设置文字的颜色
val str = """
春江潮水连海平,海上明月共潮生。
滟滟随波千万里,何处春江无月明!
江流宛转绕芳甸,月照花林皆似霰;
空里流霜不觉飞,汀上白沙看不见。
江天一色无纤尘,皎皎空中孤月轮。
江畔何人初见月?江月何年初照人?
""".trimIndent()
val ssb = SpannableStringBuilder(str)
val colors = arrayListOf("#90EE90", "#FF00FF", "#3CB371", "#FF4500", "#8B4513", "#800080")
for (index in 0 until 6) {
ssb.setSpan(
ForegroundColorSpan( Color.parseColor(colors[index])),
index*17,
(index+1)*17,
SPAN_EXCLUSIVE_EXCLUSIVE
)
}
BackgroundColorSpan
BackgroundColorSpan可以用来设置背景色
ssb.setSpan(BackgroundColorSpan(Color.parseColor("#808080")), 0, 17, SPAN_EXCLUSIVE_EXCLUSIVE)
AbsoluteSizeSpan
AbsoluteSizeSpan用来设置文字大小
ssb.setSpan(AbsoluteSizeSpan(60), 17, 34, SPAN_EXCLUSIVE_EXCLUSIVE)
StrikethroughSpan
StrikethroughSpan用来设置删除线
ssb.setSpan(StrikethroughSpan(), 34, 51, SPAN_EXCLUSIVE_EXCLUSIVE)
UnderlineSpan
UnderlineSpan用来设置下划线
ssb.setSpan(UnderlineSpan(), 51, 68, SPAN_EXCLUSIVE_EXCLUSIVE)
ImageSpan
ImageSpan用来替换图片
//将诗句中的月替换为月亮图片
val drawable = ContextCompat.getDrawable(this, R.mipmap.moon)
drawable!!.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
val span = ImageSpan(drawable, ImageSpan.ALIGN_BASELINE)
ssb.setSpan(span, 81,82, SPAN_EXCLUSIVE_EXCLUSIVE)
ClickableSpan
ClickableSpan可以添加点击事件,使用ClickableSpan的时候必须为对应的TextView设置movementMethod
textView.movementMethod = LinkMovementMethod.getInstance()
ssb.setSpan(object :ClickableSpan(){
override fun onClick(p0: View) {
Toast.makeText(this@SpanActivity,"点击事件",Toast.LENGTH_LONG).show()
}
}, 85, 101, SPAN_EXCLUSIVE_EXCLUSIVE)
以上设置效果图如下