这是一个系列文章,专门研究
Android官方提供的core-ktx库里面的扩展类、方法等等,看看能为项目开发带来哪些便利。 已更新的文章列表如下:
你需要了解的官方core-ktx库能对开发带来哪些便利1
官方core-ktx库能对SparseArray系列、Pair开发带来哪些便利?
接下来,本篇文章就带你看下富文本开发中使用到的
Span,core-ktx库会为其带来怎样的使用便利。
当前SpannableStringBuilder的使用现状
private fun test() {
val stringBuilder = SpannableStringBuilder()
var length = stringBuilder.length
stringBuilder.append("开始了")
//设置文本大小
stringBuilder.setSpan(
RelativeSizeSpan(20f),
length,
stringBuilder.length,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
length = stringBuilder.length
stringBuilder.append("执行了")
//设置背景颜色
stringBuilder.setSpan(
BackgroundColorSpan(Color.parseColor("#ffffff")),
length,
stringBuilder.length,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
length = stringBuilder.length
stringBuilder.append("结束了")
//设置点击事件
stringBuilder.setSpan(
object : ClickableSpan() {
override fun onClick(widget: View) {
}
},
length,
stringBuilder.length,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
}
以上代码就实现了三个功能,设置文本大小、背景颜色及点击事件,却写了这么一大坨代码,写起来好麻烦!!
core-ktx库的SpannableStringBuilder扩展
-
看下如何构造一个
SpannableStringBuilder:我们就可以在代码中这样使用:
private fun test4() { val build = buildSpannedString { //操作各种Span } }请注意,这个
buildSpannedString()方法的函数类型属于带接收者的函数类型,意为着我们可以访问SpannableStringBuilder定义的公共的属性方法(包括扩展方法),接下来我们就看下core-ktx库为SpannableStringBuilder提供了哪些扩展方法。 -
SpannableStringBuilder.backgroundColor()设置背景色:这个扩展方法需要传入一个
颜色值充当背景色,backgroundColor()会自动帮助我们创建一个ForegroundColorSpan对象;还可以传入一个函数类型builderAction,比如用作使用append()方法设置要渲染的文本内容,最终会调用到inSpan()方法:是不是明白了,最终我们是在这个方法中将
xxxSpan设置给SpannableStringBuilder的。最终就可以这样使用了:val build = buildSpannedString { //操作各种Span backgroundColor(Color.RED) { append("开始了") } } -
SpannableStringBuilder.bold()设置粗体:可以看到
bold()方法中会自动帮助我们创建一个StyleSpan对象,使用起来和上面差不多:val build = buildSpannedString { bold { append("开始了") } } -
其他
SpannableStringBuilder.xxx()富文本设置扩展:core-ktx库提供了很多富文本设置的扩展方法,这里就只介绍上面的两个,其他的就不再这里介绍了,可以自行看下源码: -
一个非常非常简单的使用技巧
假设当前有一小段文本
遮天是一群人的完美,完美是一个人的遮天,我想要对整段文本设置一个背景色,对一群人这三个字设置一个粗体大小,利用上面core-ktx库提供的扩展,我们可以这样实现:private fun test4() { val build = buildSpannedString { backgroundColor(Color.RED) { append("遮天是") bold { append("一群人") } append("的完美,完美是一个人的遮天") } } }核心就是
SpannableStringBuilder.xxx()系列的富文本扩展方法的第二个参数是一个接收者为SpannableStringBuilder的函数类型,所以backgroundColor()、bold()、strikeThrough()等等可以相互嵌套使用,从来更简单的实现一些富文本效果。
使用时请注意,
buildSpannedString()这个方法创建的SpannableStringBuilder最终会包装成一个SpannedString不可变对象,请根据实际情况使用。
core-ktx库的Spannable扩展
SpannableStringBuilder、SpannableString等实现了Spannable接口,所以Spannable定义的扩展方法对常用的SpannableStringBuilder、SpannableString同样适用。
-
Spannable.clearSpans清理所有标识(包括各种Span)使用时,直接对
Spannable及其子类调用clearSpans()即可。 -
Spannable.set(start: Int, end: Int, span: Any)设置Span这个扩展方法就比较牛逼了,它是一个
运算符重载函数且重载了[xxx]运算符来设置Span的,我们看下使用:val stringBuilder = SpannableStringBuilder() //设置背景色 stringBuilder[0, 2] = BackgroundColorSpan(Color.RED)有没有眼前一亮的感觉哈!!
-
Spannable.set(range: IntRange, span: Any)设置Span这个方法和上一个方法很像,不过传入的设置Span标识范围的方式发生了改变,变成了一个
IntRange类型,我们直接看下使用:val stringBuilder = SpannableStringBuilder() //设置背景色 stringBuilder[0..3] = BackgroundColorSpan(Color.RED) -
CharSequence.toSpannable()转换CharSequence为SpannableString这个很简单,就不再进行举例说明了。
core-ktx库的Spanned扩展
Spanned的子接口包括我们上面刚讲到的Spannable,所以它定义的扩展方法对于SpannableStringBuilder、SpannableString同样适用。
-
CharSequence.toSpanned()转换CharSequence为SpannedString注意和
isSpannable()转换的区别,一个能设置Span,一个不能设。 -
Spanned.getSpans()获取指定类型的Span标识借助于Kotlin的泛型实化
reified+inline简化了传入具体Span类型的逻辑,我们看下使用:private fun test4(builder: SpannableStringBuilder) { val spans = builder.getSpans<BackgroundColorSpan>() }获取类型为
BackgroudColorSpan的所有Span对象,如果我们想要获取所有的Span对象,直接将传入的泛型类型改为Any即可。 -
Spanned.toHtml()将富文本转换成同等效果显示的html代码也就是说如果你富文本中存在
ImageSpan,转换成html代码时,就会帮你在对应位置添加一个<img src="" />的标签,我们简单看下其核心源码Html.withinParagraph()中的片段:
富文本绘制复杂布局的两种技巧
-
ReplacementSpan这个Span使用非常灵活,它提供了方法draw()可自定义绘制你想要的布局效果; -
如果使用
ReplacementSpan自定义绘制布局还是太过于复杂,可以考虑先使用原生组件在xml中实现这个布局效果,然后将这个xml通过Inflate转换成View,并将调用View的onDraw()方法,手动绘制到我们自定义Bitmap中,经过这个流程,我们就将这个复杂的布局转换成了Bitmap图像,然后使用ImageSpan加载该Bitmap,最终渲染到富文本中即可。请注意,请根据实际情况判断,是否需要先手动测量这个转换的
View,然后再将其绘制到我们自定义的Bitmap中,否则可能不生效。
总结
以上就是core-ktx库针对于富文本提供的所有扩展方法,核心的源码就在SpannableStringBuilder.kt、SpannableString.kt、SpannedString.kt这三个文件中,大家有需要请自行查看。
-
我正在参与技术社区创作者签约计划招募活动,点击链接报名投稿。














评论(0)