修改TextView中部分文本的字体及颜色

在Android应用开发中使用TextView控件展示一些文字内容时可能会遇到一些特别的需求,比如希望用特殊的字体或颜色标示出一段文字中的某些文字,一般开发者很容易想到用多个TextView控件把具有不同显示样式的文字拼接起来,这样能够实现,但是相对比较麻烦一些,而且扩展性和显示效果都不一定很好。本文是结合我在实际工作中遇到的需求的解决办法和我对这个问题的一点调查总结形成的博文,以备以后查阅。

实现方法

要实现一段文字中部分文字内容的字体大小颜色与众不同的需求,一般有三种实现方式:
1、使用多个TextView拼接
2、使用html标签定义文字内容,用Html.fromHtml()方法解析后设置给TextView控件
3、使用Spannable对象动态设置文字的大小和颜色

使用多个TextView控件来依次拼接具有不同属性的文字,这种方法没有什么特别的,只需要正确地设置TextView的各种属性就可以实现需求。下面分别说说Html标签和Spannable的使用。

Html标签设置字体大小、颜色

Android SDK中提供了一个Html类用来解析HTML格式的字符串用于显示,所以可以通过Html标签来设置文字的显示属性,不过这个Html类并不支持所有的Html标签。

/**
 * 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文件里面,不过我们需要注意对<、>、'、"这些字符进行转换,因为它们四个是HTML的标签,放到xml文件中需要对其进行转义。具体来说,左括号< 要用 < 代替,右括号> 要用 > 代替,单引号和双引号要用 \ 进行转义。

在strings.xml中定义文字内容:

<string name="partly_colored_text">修改TextView中部分文字的<font color=\'#ff0000\'> <big>大</big> <small>小</small> </font>和<font color=\'#00ff00\'>颜色</font>,展示多彩效果!</string>

在Java代码中调用:

textView.setText(Html.fromHtml(getString(R.string.partly_colored_text)));

两种实现方式效果一样,同上图片。

Spannable

Spannable是android.text包下的一个关于文字样式处理的接口类,可以给文字添加或者去除一些显示样式,有三个类实现了Spannable,其中Editable也是一个接口,由SpannableStringBuilder最终实现,Spannable本身实现了Spanned接口,在Android SDK中的类结构关系如下图。


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)便可以构造带有我们需要的显示样式的Spanned对象,然后将这个对象传入TextView的setText方法即可让目标字符串显示为设置的样式。这里setSpan方法中what就是SDK中提供的各种CharacterStyle对象;start和end是设置这个样式针对的textview中的字符起止位置;flags是Spanned类中定义的几种标志,用来表示是否要将前面设置的起点或终点位置设置成what标示的样式。这些flags大概的意思如下

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE (前后都不包括)
Spanned.SPAN_INCLUSIVE_EXCLUSIVE (前面包括,后面不包括)
Spanned.SPAN_EXCLUSIVE_INCLUSIVE (前面不包括,后面包括)
Spanned.SPAN_INCLUSIVE_INCLUSIVE (前后都包括)

小结

灵活应用Spannable可以实现非常多酷炫的TextView显示效果,本文没有写代码演示各种TextView样式的效果,下面最后一个链接的文章给出了一些效果的用法示例,非常不错,参考之;第二个链接地址中作者给出了一个使用Spannable的工具类,挺方便实用的。

Thanks To

给TextView加上多彩效果:改变部分字体的大小和颜色
TextView的一些高级应用(自定义字体、显示多种颜色、添加阴影)
通过Spannable对象设置textview的样式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,423评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,339评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,241评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,503评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,824评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,262评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,615评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,337评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,989评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,300评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,829评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,193评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,753评论 3 230
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,970评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,708评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,295评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,207评论 2 258

推荐阅读更多精彩内容