最近一直在作 TextView 富文本处理的工做,接触到了比较纤细的粗
、字体颜色
、内联图片
、处理 ellipsize
、LinkMovementMethod 的坑
和ClickableSpan 的点击事件
等问题,通过查资料
、看源码
和作实验
三连以后,对 Android TextView 的富文本处理有了小小的体会,写篇博客总结下本身的收获,往后在遇到相似问题也方便回顾。android
富文本相关的 xxxSpan
基本都在这个包下面啦,android-28
里的有 42 个文件,包含了各式各样设置字体
、自定义绘制
、点击事件
、段落样式
的 Span。canvas
多数 Span 的基类,有一个抽象方法:
public abstract void updateDrawState(TextPaint tp);
TextPaint 继承自 Paint,这就给了咱们一个机会去操纵画笔,设置前景色
、背景色
、字体颜色
、字体粗细
、字体大小
等等等等,想怎么设置怎么设置。bash
设计:这里的用户名要单独加粗
我:好,加粗
设计:不行,这样太粗了,要那种比较纤细的粗
我:我 。。。
复制代码
Paint.setFakeBoldText
就适用于这种状况,这个方法其实就是把画笔变粗了而已,而不是使用粗体的字体,要更精细地控制画笔粗细能够用Paint.setStrokeWidth
。
附上解决问题连接: 如何实现 “中间这几个字要加粗,可是不要太粗,比较纤细的那种粗” ?布局
UpdateLayout
稍后说,其余的 Span 都实现
CharacterStyle
的
updateDrawState
方法,并对画笔进行设置,达到变换字体外观的目的。
增长了一个抽象方法public abstract void onClick(@NonNull View widget);
,用于响应点击事件(须要外部配合,如 LinkMovementMethod
或OnTouchListener
)。
URLSpan
继承自它,存储一个 URL,点击时用 startActivity
打开。post
UpdateAppearance
同样是一个标识,从名字就能看出来,它还改变布局(位置、大小等), 惟一的继承类
MetricAffectingSpan
有一个抽象方法
public abstract void updateMeasureState(@NonNull TextPaint textPaint);
,用于改变字体的大小等属性。
Paint
,能作的事情颇有限,
ReplacementSpan
比
MetricAffectingSpan
更进一步,直接本身接管了绘制的任务,它有两个抽象方法
public abstract int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm);
和
public abstract void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint);
分别用于肯定绘制范围和绘制内容。这就使得
ReplacementSpan
有很大的灵活性,想画啥就画啥,常常用于画内联的图片之类的东西。
ParagraphStyle
相关的也有不少 Span,主要用于段落样式的处理,我也没用过,就不瞎说了 字体
TtsSpan
、
SuggestionSpan
、
EasyEditSpan
、
SpellCheckSpan
、
SuggestionRangeSpan
。。。
Android 提供了这么多 Span,我平时用的比较多的也就ReplacementSpan
和ClickableSpan
,ReplacementSpan
用于现实自定义的 emoji 表情和内联的一些小图标之类的,ClickableSpan
则用于自定义点击事件,好比在点击@Somebody
、#话题#
、查看图片
等操做时,用本地的页面打开。这两个 Span 用的比较多,坑也比较多,接下来会专门对这两个 Span 作个稍微详细的总结。
Html.fromHtml
实现的富文本处理其实也是利用 Android 提供的 Span 实现,只不过 TextView 支持的标签十分有限,作一些简单的处理还行,毕竟 TextView 主要显示文本嘛,干吗整那么复杂。我平时用的时候也主要是用超连接
,而后经过自定义的ClickableSpan
和Route
打开本地页面。spa