在Android應(yīng)用開發(fā)中使用TextView控件展示一些文字內(nèi)容時可能會遇到一些特別的需求,比如希望用特殊的字體或顏色標(biāo)示出一段文字中的某些文字,一般開發(fā)者很容易想到用多個TextView控件把具有不同顯示樣式的文字拼接起來,這樣能夠?qū)崿F(xiàn),但是相對比較麻煩一些,而且擴展性和顯示效果都不一定很好。本文是結(jié)合我在實際工作中遇到的需求的解決辦法和我對這個問題的一點調(diào)查總結(jié)形成的博文,以備以后查閱。
實現(xiàn)方法
要實現(xiàn)一段文字中部分文字內(nèi)容的字體大小顏色與眾不同的需求,一般有三種實現(xiàn)方式:
1、使用多個TextView拼接
2、使用html標(biāo)簽定義文字內(nèi)容,用Html.fromHtml()方法解析后設(shè)置給TextView控件
3、使用Spannable對象動態(tài)設(shè)置文字的大小和顏色
使用多個TextView控件來依次拼接具有不同屬性的文字,這種方法沒有什么特別的,只需要正確地設(shè)置TextView的各種屬性就可以實現(xiàn)需求。下面分別說說Html標(biāo)簽和Spannable的使用。
Html標(biāo)簽設(shè)置字體大小、顏色
Android SDK中提供了一個Html類用來解析HTML格式的字符串用于顯示,所以可以通過Html標(biāo)簽來設(shè)置文字的顯示屬性,不過這個Html類并不支持所有的Html標(biāo)簽。
/**
* This class processes HTML strings into displayable styled text.
* Not all HTML tags are supported.
*/
public class Html {
……
/**
* Returns displayable styled text from the provided HTML string.
* Any <img> tags in the HTML will display as a generic
* replacement image which your program can then go through and
* replace with real images.
*
* <p>This uses TagSoup to handle real HTML, including all of the
* brokenness found in the wild.
*/
public static Spanned fromHtml(String source) {
return fromHtml(source, null, null);
}
/**
* Returns displayable styled text from the provided HTML string.
* Any <img> tags in the HTML will use the specified ImageGetter
* to request a representation of the image (use null if you don't
* want this) and the specified TagHandler to handle unknown tags
* (specify null if you don't want this).
*
* <p>This uses TagSoup to handle real HTML, including all of the
* brokenness found in the wild.
*/
public static Spanned fromHtml(String source, ImageGetter imageGetter,
TagHandler tagHandler) {
//implementation code
}
……
}
代碼示例
TextView textView = (TextView) findViewById(R.id.text_for_test);
String textSource = "修改TextView中部分文字的<font color='#ff0000'><big>大</big><small>小</small></font>和<font color='#00ff00'>顏色</font>,展示多彩效果!";
textView.setText(Html.fromHtml(textSource));
顯示效果如下

我們也可以把要顯示的文本加到strings.xml文件里面,不過我們需要注意對<、>、'、"這些字符進行轉(zhuǎn)換,因為它們四個是HTML的標(biāo)簽,放到xml文件中需要對其進行轉(zhuǎn)義。具體來說,左括號< 要用 < 代替,右括號> 要用 > 代替,單引號和雙引號要用 \ 進行轉(zhuǎn)義。
在strings.xml中定義文字內(nèi)容:
<string name="partly_colored_text">修改TextView中部分文字的<font color=\'#ff0000\'> <big>大</big> <small>小</small> </font>和<font color=\'#00ff00\'>顏色</font>,展示多彩效果!</string>
在Java代碼中調(diào)用:
textView.setText(Html.fromHtml(getString(R.string.partly_colored_text)));
兩種實現(xiàn)方式效果一樣,同上圖片。
Spannable
Spannable是android.text包下的一個關(guān)于文字樣式處理的接口類,可以給文字添加或者去除一些顯示樣式,有三個類實現(xiàn)了Spannable,其中Editable也是一個接口,由SpannableStringBuilder最終實現(xiàn),Spannable本身實現(xiàn)了Spanned接口,在Android SDK中的類結(jié)構(gòu)關(guān)系如下圖。

Spannable接口繼承了Spanned接口,而后者又繼承了CharSequence接口,所以通過實例化Spannable對象我們可以為一個字符串添加各種顯示樣式,可添加的字符樣式包括抽象類CharacterStyle的各個可實例化子類提供的樣式。
CharacterStyle
public abstract class CharacterStyle
extends Object
java.lang.Object
android.text.style.CharacterStyle
Known Direct Subclasses BackgroundColorSpan, ClickableSpan, ForegroundColorSpan, MaskFilterSpan, MetricAffectingSpan, RasterizerSpan, StrikethroughSpan,SuggestionSpan, UnderlineSpan
Known Indirect Subclasses AbsoluteSizeSpan, DynamicDrawableSpan, ImageSpan, LocaleSpan, RelativeSizeSpan, ReplacementSpan, ScaleXSpan, StyleSpan, SubscriptSpan,SuperscriptSpan, TextAppearanceSpan, TypefaceSpan, URLSpan
實例化SpannableString對象并通過它的方法setSpan(Object what, int start, int end, int flags)便可以構(gòu)造帶有我們需要的顯示樣式的Spanned對象,然后將這個對象傳入TextView的setText方法即可讓目標(biāo)字符串顯示為設(shè)置的樣式。這里setSpan方法中what就是SDK中提供的各種CharacterStyle對象;start和end是設(shè)置這個樣式針對的textview中的字符起止位置;flags是Spanned類中定義的幾種標(biāo)志,用來表示是否要將前面設(shè)置的起點或終點位置設(shè)置成what標(biāo)示的樣式。這些flags大概的意思如下
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE (前后都不包括)
Spanned.SPAN_INCLUSIVE_EXCLUSIVE (前面包括,后面不包括)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE (前面不包括,后面包括)
Spanned.SPAN_INCLUSIVE_INCLUSIVE (前后都包括)
小結(jié)
靈活應(yīng)用Spannable可以實現(xiàn)非常多酷炫的TextView顯示效果,本文沒有寫代碼演示各種TextView樣式的效果,下面最后一個鏈接的文章給出了一些效果的用法示例,非常不錯,參考之;第二個鏈接地址中作者給出了一個使用Spannable的工具類,挺方便實用的。
Thanks To
給TextView加上多彩效果:改變部分字體的大小和顏色
TextView的一些高級應(yīng)用(自定義字體、顯示多種顏色、添加陰影)
通過Spannable對象設(shè)置textview的樣式