1 Span用处:可以修改TextView中的部分文字的字体,如加粗、下划线、修改颜色、行对齐方式、首行缩进、插入图片等等。具体 android.text.style.* 中寻找自己想要的Span。
2 Span使用方法
SpannableString的setSpan(...)方法。然后TextView的setText方法中使用SpannableString代替String。(用SpannableStringBuilder代替String更佳)。
一个例子:
CharSequence mText = new
mText.setSpan(new UnderlineSpan(), 0, mText.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(mText);
3 绘制Span的内部实现
一条重要线索
TextView --> DynamicLayout --> Layout的draw方法--> TextLine的draw方法
首先看TextView,在TextView中用于绘制文字的是Layout mLayout这个变量,这在TextView的onDraw方法中体现。当TextView发现显示的文字是继承自Spannable的(比如于SpannableString),mLayout这个类便初始化为DynamicLayout类,否则为StaticLayout,在makeSingleLayout(...)方法中有体现。
DynamicLayout可以用于对文字Span样式的修改,而StaticLayout不可以,他们的主要不同在于DynamicLayout多了reflow()方法,reflow()方法用于。。。说不清楚,举个例子。
如:“我是绿色”。Span属性为绿色Span,index为从0到4。如果文字变为“我真的是绿色”,Span属性为绿色Span,index为从0到6。这个index的变化就是reflow()方法干的事情。
===============================丝丝分割线========================================
真正绘制的方法并不在DynamicLayout内,而是父类Layout的draw方法中。
在Layout中首先绘制了段落的背景颜色,然后分了行,然后所有的绘制操作交给了TextLine的draw方法来绘制每一行的文本。
Span分为两种类型,一种是ParagraphStyle,另一种是CharacterStyle。ParagraphStyle是用在段落的Span,而CharacterStyle是用在文字上的Span。
CharacterStyle又分为两种类型,一种是ReplacementSpan,一种是CharacterStyle本身。
如果TextLine遇到CharacterStyle则直接调用它的updateDrawState(TextPaint)方法对样式进行修改,然后再把文本绘制出来。否则会调用ReplacementSpan的draw方法代替文本的绘制。
所以,如果想自己重写一个Span,则需考虑这个使用哪一种类型Span,比如我想写一个原笔迹显示代替文本显示的Span则需继承ReplacementSpan然后重写ReplacementSpan的draw方法显示出原笔迹即可。