Android图文混排初窥
背景
在使用textview时,常常会有文本混排的需求(一段文本中具有多个样式),如标题开头的标签,聊天消息中的表情等,考虑到不同尺寸屏幕的适配问题,简单粗暴地使用多个textView并不能满足要求。
解决方案
Android官方对文本/图文混排提供了支持:
- 在TextView的XML布局文件中添加Compound Drawable属性;
- 在对TextView设置字符串时,可以设置Html类型的字符串。Html.fromHtml()方法可以对Html的字符串进行处理,从而使得Html类型的内容满足TextView的要求。在给TextView设置Html类型的内容时,还可以传入一个ImageGetter,从而对Html类型内容中的图片进行处理;
- 对TextView设置内容的时候,可以传入CharSequence类型,而一些CharSequence类型可以利用CharacterStyle进行修饰,从而展现出丰富多彩的内容。CharacterStyle拥有很多子类(BackgroundColorSpan,ClickableSpan,ImageSpan,TypefaceSpan等),可以产生出各种各样的效果。
这里主要就最复杂也最强大的第三种方式展开讨论。
CharSequence & Span
在讲述CharSeqeuence之前,有必要先明确一点,TextView能利用上述第三种方式实现文本混排的前提是String实现了CharSequence接口,因此支持利用CharSequence的特性进行修饰定制。
Span的命名乍看之下可能有些令人费解,跨度/区间——很难和文本联系起来,更不用说猜想它的作用了:(支持丰富样式的文本)区间。
使用Span方式实现TextView图文混排的整体流程是:
- 创建一个SpannableString或者SpannableStringBuilder对象;
- 利用setSpan(Object what, int start, int end, int flags)方法,将SpannableString或者SpannableStringBuilder对象的某些位置的内容替换为具体类型的Span;
- 利用TextView的setText(CharSequence text)方法将SpannableString或者SpannableStringBuilder对象进行展示。
其中SpannableString和SpannableStringBuilder这两个类实现了Spannable接口,实现了接口里面定义的方法。
setSpan中中what通常指各种类型的span(ImageSpan、URLSpan、ClickableSpan等),不展开赘述,字面意义上看是支持image,url,clickable的span样式。
span除了从支持的特性划分,还可以从影响到的范围来划分:
如果一个Span影响字符级的文本格式,则继承CharacterStyle;
如果一个Span影响段落层次的文本格式,则实现ParagraphStyle;
如果一个Span修改字符级别的文本外观,则实现UpdateAppearance;
如果一个Span修改字符级文本度量|大小,则实现UpdateLayout。
段落级Span样式:ParagraphStyle
主要实现有以下几种:
- LeadingMarginSpan:用来处理像word中项目符号一样的接口;
- AlignmentSpan:用来处理整个段落对其的接口;
- LineBackgroundSpan:用来处理一行的背景的接口;
- LineHeightSpan:用来处理一行高度的接口;
- TabStopSpan:用来将字符串中的”\t”替换成相应的空行
先讲解ParagraphStyle实现中较为简单的LeadingMarginSpan:
该实现主要有以下两个接口方法,可用来控制文本段落偏移,并在偏移的一侧实现一些效果绘制(如列表项开头的小圆点 )
1 | /** |
其中比较重要的一个概念是排版印刷学科中的基线:即字母排列的基准线
字体中,字母向下延伸超过基线的笔画部分,称为降部。
相对的,字体的字母中向上超过主线笔画的部分,也就是比x字高还要高的部分,称为升部。
以下是引自wiki的基线准则
可以将其简单的理解为文字的“重心”位置。
抛砖引玉
准备这次分享所学习到的内容,其实仅仅是帮助我踏入了Android文本特效的大门,因为临近期末,个人时间安排方面的一些原因,还有很多方面没有涉及到,后续有机会再总结。
以下为本次分享依赖的一些参考: