无题
Android 富文本.md
**Android富文本的实现的几种方式
**在Android开发过程中,最常见的富文本场景一般都是变色,点击跳转,或者局部变大,而我们实现的方式通常分为两种。
一种是Html的方式定义在string中,通过html标签变色,变大,通过占位符填充数据。一般常用于有国际化的需求。
另一种是CharSequence的setSpan设置自定义Span。功能更强大,细读也更细,便于精准操作。一般用于没有国际化需求的地方。
为什么有国际化相关的要求,是因为一般setSpan的方式都是添加或者根据索引替换对应的文本,如果国际化之后中英马等语言的顺序都变了,自然效果就不同了。当然也可以通过判断语言进行不同的操作。这是后话了。
一,Html的方式实现
1.1 占位符的处理
先看看string xml中如何处理占位符 %N代表第N个参数,如%3代表的是第三个参数; $是结束符;
1 | <string name="string_test_1">学号:%1$d ;姓名:%2$s ;成绩:%3$.2f</string> |
使用的时候:
1 | String testStr = getResources().getString(R.string.string_test_1); |
1.2 Html的占位符
和上面的差不多:
1 | <string name="purchase_points"><![CDATA[ <font color="#767676">Purchase with</font> |
使用:
1 | String formatPoints = PointFormatUtils.formatPoints(points); |
注:Html.fromHtml还分Android N的兼容处理,需要传入Model,不同的Model展示的效果有所不同,这里不做展开。其实效果大差不差。
实现效果:
结论:
能实现变色,简单的变大等简单功能,由于TextView不能解析更多的Html标签,由此还出现了一些库,让TextView支持更多标签,但是我们Android实现富文本本身就是小功能,还得依赖库支持更多标签也都用不上,得不偿失啊。
如果有一些自定义的需求,我们可以使用自定义标签+自定义标签的功能,例如Html中的自定义字体
1.2 自定义Html标签
先定义自定义字体的Span类
1 | /** |
自定义标签:
1 | /** |
定义Xml并使用,注意自定义face标签
1 | String content = "<font color=\"#000000\">HR from </font>" + |
效果如下:
如果想实现其他的变大 下划线 中划线等Span效果,都可以通过自定义的Html标签+自定义Span实现相应的效果。
二,Span的几种实现方式
虽然通过Html的方式可以实现各种效果,但是定义的时候也太过复杂,各种定义Span 定义标签之类的,有没有更简单和直接的?
有,我们直接封装Span就行了。
2.1 java - SpanUtil
在Java中我们可以封装工具类一个如下:
1 | /** |
2.2 kotlin扩展
1 | /** |
扩展方法的使用
1 | mBinding.tvTextSpan1.text = "演示一下appendXX方法的用法\n" |
效果:
2.3 kotlin DSL方式
如果是使用Kotlin的语言开发,那么还有更简单的DSL封装方式:
第一层的DSL接口
1 | interface DslSpannableStringBuilder { |
第一层的DSL接口实现
1 | class DslSpannableStringBuilderImpl : DslSpannableStringBuilder { |
第二层Text的DSL接口
1 | interface DslSpanBuilder { |
第二层Text的DSL接口实现
1 | class DslSpanBuilderImpl : DslSpanBuilder { |
创建TextVuew的扩展入口
1 | //为 TextView 创建扩展函数,其参数为接口的扩展函数 |
使用:
1 | mBinding.tvTextSpan4.buildSpannableString { |
效果:
总结
如果是顺序固定,效果复杂,那么可以用Span的方式。
如果顺序不固定(如国际化)那么可以使用Html的方式。
总的来说,两种方式都不算太难,都是些固定的代码。如果需求可以看源码。