前言
有一段文本,如果需要单独给它各部分文字设置不同的样式,有的文字设置为粗体,有的文字设置特殊的颜色,有的地方要加入表情/图片,遇到数学公式还可能要设置上下标,这时候就可以借助SpannableString
实现啦~
什么是 SpannableString?
SpannableString
,是 CharSequence
的一种,原本的 CharSequence
只是一串字符序列,没有任何样式,而 SpannableString
可以在字符序列基础上对指定的字符进行润饰,在开发中,TextView
可以通过 setText(CharSequence)
传入SpannableString
作为参数,来达到显示不同样式文字的效果。
如何对 SpannableString 进行润饰?
一般通过以下方式进行设置
spannableString.setSpan(Object what, int start, int end, int flags);
这里讲解一下几个参数的意义
what
:对 SpannableString 进行润色的各种 Span;int
:需要润色文字段开始的下标;end
:需要润色文字段结束的下标;flags
:决定开始和结束下标是否包含的标志位,有四个参数可选
SPAN_INCLUSIVE_EXCLUSIVE
:左闭右开区间SPAN_EXCLUSIVE_INCLUSIVE
:左开右闭区间SPAN_INCLUSIVE_INCLUSIVE
:闭区间SPAN_EXCLUSIVE_EXCLUSIVE
:开区间
这里涉及到一个重要的角色,就是各种各样的 span,它决定我们要对文字的进行怎样的润饰,而后三个参数决定润饰哪些文字。
由于Span种类繁多,这里不再一一赘述各自的使用方法,而是需求中用到的ImageSpan为例,介绍其使用方法。
- 构造一个SpannableString,想构造器传入需要设置的文字
- 构造一个ImageSpan,并向其传入需要设置的图片(ImageSpan有多种构造器可以使用,可根据需要进行挑选)
- 将构造出的Span设置给SpannableString
这样,我们就拿到了一段将图片作为富文本的文本了~
SpannableString spannableString = new SpannableString("如果我是陈奕迅");
ImageSpan imageSpan = new ImageSpan(this, R.drawable.ic_eason);
spannableString.setSpan(imageSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(spannableString);
在ImageSpan中,本例的构造器会调用ImageSpan(Context context, int drawableId, int align)
,第三个参数为对齐方式,默认传递ALIGN_BOTTOM
值,代表该Image与底部对齐,此外还有ALIGN_BASELINE
与对API版本有要求的ALIGN_CENTER
。
与String
和StringBuilder
类似,SpannableString
也有其构造类SpannableStringBuilder
,使用方法也相当类似。
问题:图文不居中
由于文本设置了行距,该设置对通过SpannableString配置的图片并不产生作用,从而导致图文显示不居中。
对此,有两种解决方案:
方案一:两个TextView
在显示内容TextView前增设一个TextView,以显示富文本,来避免被行距效果影响到。但这样控制成本较高。
方案二:自定义ImageSpan
可以通过重写onDraw()使image自适应的绘制,来实现图文的居中对齐。
关于Android使用TextView+ImageSpan同一行文字图片居中的问题