http://blog.csdn.net/fengkuanghun/article/details/7904284

背景介绍

在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的LockScreen上面的时间和充电信息。对于类似的情况,可能第一反应就是用不同的多个TextView来实现,对于每个TextView设置不同的字体风格以满足需求。

这里推荐的做法是使用android.text.*;和 android.text.style.*;下面的组件来实现RichText:也即在同一个TextView中设置不同的字体风格。对于某些应用,比如文本编辑,记事本,彩信,短信等地方,还必须使用这些组件才能达到想到的显示效果。

主要的基本工具类有android.text.Spanned; android.text.SpannableString; android.text.SpannableStringBuilder;使用这些类来代替常规String。SpannableString和 SpannableStringBuilder可以用来设置不同的Span,这些Span便是用于实现Rich Text,比如粗体,斜体,前景色,背景色,字体大小,字体风格等等,android.text.style.*中定义了很多的Span类型可供使用。

这是相关的API的Class General Hierarchy:

因为Spannable等最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。

使用方法

当要显示Rich Text信息的时候,可以使用创建一个SpannableString或SpannableStringBuilder,它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String:

SpannableString word = new SpannableString("The quick fox jumps over the lazy dog");

SpannableStringBuilder multiWord = new SpannableStringBuilder();
multiWord.append("The Quick Fox");
multiWord.append("jumps over");
multiWord.append("the lazy dog");

创建完Spannable对象后,就可以为它们设置Span来实现想要的Rich Text了,常见的Span有:

  • AbsoluteSizeSpan(int size) ---- 设置字体大小,参数是绝对数值,相当于Word中的字体大小
  • RelativeSizeSpan(float proportion) ---- 设置字体大小,参数是相对于默认字体大小的倍数,比如默认字体大小是x, 那么设置后的字体大小就是x*proportion,这个用起来比较灵活,proportion>1就是放大(zoom in), proportion<1就是缩小(zoom out)
  • ScaleXSpan(float proportion) ---- 缩放字体,与上面的类似,默认为1,设置后就是原来的乘以proportion,大于1时放大(zoon in),小于时缩小(zoom out)
  • BackgroundColorSpan(int color) ----背景着色,参数是颜色数值,可以直接使用android.graphics.Color里面定义的常量,或是用Color.rgb(int, int, int)
  • ForegroundColorSpan(int color) ----前景着色,也就是字的着色,参数与背景着色一致
  • TypefaceSpan(String family) ----字体,参数是字体的名字比如“sans", "sans-serif"等
  • StyleSpan(Typeface style) -----字体风格,比如粗体,斜体,参数是android.graphics.Typeface里面定义的常量,如Typeface.BOLD,Typeface.ITALIC等等。
  • StrikethroughSpan----如果设置了此风格,会有一条线从中间穿过所有的字,就像被划掉一样

对于这些Sytle span在使用的时候通常只传上面所说明的构造参数即可,不需要设置其他的属性,如果需要的话,也可以对它们设置其他的属性,详情可以参见文档
SpannableString和SpannableStringBuilder都有一个设置上述Span的方法:

/**
* Set the style span to Spannable, such as SpannableString or SpannableStringBuilder
* @param what --- the style span, such as StyleSpan
* @param start --- the starting index of characters to which the style span to apply
* @param end --- the ending index of characters to which the style span to apply
* @param flags --- the flag specified to control
*/
setSpan(Object what, int start, int end, int flags);

其中参数what是要设置的Style span,start和end则是标识String中Span的起始位置,而 flags是用于控制行为的,通常设置为0或Spanned中定义的常量,常用的有:

  • Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含两端start和end所在的端点
  • Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点
  • Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含两端start,但不包含end所在的端点
  • Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含两端start和end所在的端点

这里理解起来就好像数学中定义区间,开区间还是闭区间一样的。还有许多其他的Flag,可以参考这里。这里要重点说明下关于参数0,有很多时候,如果设置了上述的参数,那么Span会从start应用到Text结尾,而不是在start和end二者之间,这个时候就需要使用Flag 0。

Linkify

另外,也可以对通过TextView.setAutoLink(int)设置其Linkify属性,其用处在于,TextView会自动检查其内容,会识别出phone number, web address or email address,并标识为超链接,可点击,点击后便跳转到相应的应用,如Dialer,Browser或Email。Linkify有几个常用选项,更多的请参考文档

  • Linkify.EMAIL_ADDRESS -- 仅识别出TextView中的Email在址,标识为超链接,点击后会跳到Email,发送邮件给此地址
  • Linkify.PHONE_NUMBERS -- 仅识别出TextView中的电话号码,标识为超链接,点击后会跳到Dialer,Call这个号码
  • Linkify.WEB_URLS-- 仅识别出TextView中的网址,标识为超链接,点击后会跳到Browser打开此URL
  • Linkify.ALL -- 这个选项是识别出所有系统所支持的特殊Uri,然后做相应的操作

权衡选择

个人认为软件开发中最常见的问题不是某个技巧怎么使用的问题,而是何时该使用何技巧的问题,因为实现同一个目标可能有N种不同的方法,就要权衡利弊,选择最合适的一个,正如常言所云,没有最好的,只有最适合的。如前面所讨论的,要想用不同的字体展现不同的信息可能的解法,除了用Style Span外还可以用多个TextView。那么就需要总结下什么时候该使用StyleSpan,什么时候该使用多个TextView:

    1. 如果显示的是多个不同类别的信息,就应该使用多个TextView,这样也方便控制和改变各自的信息,例子就是默认LockScreen上面的日期和充电信息,因为它们所承载不同的信息,所以应该使用多个TextView来分别呈现。
    2. 如果显示的是同一类信息,或者同一个信息,那么应该使用StyleSpan。比如,短信息中,要把联系人的相关信息突出显示;或是想要Highlight某些信息等。
    3. 如果要实现Rich text,没办法,只能使用Style span。
    4. 如果要实现某些特效,也可以考虑使用StyleSpan。设置不同的字体风格只是Style span的初级应用,如果深入研究,可以发现很多奇妙的功效。

Spannable与ImageSapn结合使用可实现在EditText中实现图文混排的效果

http://blog.csdn.net/ah200614435/article/details/7914459

下面是一些实例代码

  1. /**
  2. * 超链接
  3. */
  4. private void addUrlSpan() {
  5. SpannableString spanString = new SpannableString("超链接");
  6. URLSpan span = new URLSpan("tel:0123456789");
  7. spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  8. tv.append(spanString);
  9. }
  10. /**
  11. * 文字背景颜色
  12. */
  13. private void addBackColorSpan() {
  14. SpannableString spanString = new SpannableString("颜色2");
  15. BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);
  16. spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  17. tv.append(spanString);
  18. }
  19. /**
  20. * 文字颜色
  21. */
  22. private void addForeColorSpan() {
  23. SpannableString spanString = new SpannableString("颜色1");
  24. ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);
  25. spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  26. tv.append(spanString);
  27. }
  28. /**
  29. * 字体大小
  30. */
  31. private void addFontSpan() {
  32. SpannableString spanString = new SpannableString("36号字体");
  33. AbsoluteSizeSpan span = new AbsoluteSizeSpan(36);
  34. spanString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  35. tv.append(spanString);
  36. }
  37. /**
  38. * 粗体,斜体
  39. */
  40. private void addStyleSpan() {
  41. SpannableString spanString = new SpannableString("BIBI");
  42. StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);
  43. spanString.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  44. tv.append(spanString);
  45. }
  46. /**
  47. * 删除线
  48. */
  49. private void addStrikeSpan() {
  50. SpannableString spanString = new SpannableString("删除线");
  51. StrikethroughSpan span = new StrikethroughSpan();
  52. spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  53. tv.append(spanString);
  54. }
  55. /**
  56. * 下划线
  57. */
  58. private void addUnderLineSpan() {
  59. SpannableString spanString = new SpannableString("下划线");
  60. UnderlineSpan span = new UnderlineSpan();
  61. spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  62. tv.append(spanString);
  63. }
  64. /**
  65. * 图片
  66. */
  67. private void addImageSpan() {
  68. SpannableString spanString = new SpannableString(" ");
  69. Drawable d = getResources().getDrawable(R.drawable.ic_launcher);
  70. d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
  71. ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
  72. spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  73. tv.append(spanString);
  74. }
  75. }

SpannableString的更多相关文章

  1. TextView使用SpannableString设置复合文本(转)

    TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.Bac ...

  2. Android TextView中文字通过SpannableString来设置超链接、颜色、字体等属性

    在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及 ...

  3. 利用SpannableString设置文本

    private void setTips(){ String big = "大字深色"; String small = "小字淡色"; Spannable ti ...

  4. 设置TextView下划线并响应点击事件(SpannableString)

    下面是一个20行的完整Demo代码:基本原理是使用一个SpannableString并设置其ClickableSpan来响应点击事件. TextView useInfo = (TextView) fi ...

  5. TextView使用SpannableString设置复合文本

    TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.Bac ...

  6. [Android教程]TextView使用SpannableString设置复合文本

    TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.Bac ...

  7. *像word一样编辑复杂的文本:SpannableString 样式详介

    简介: 使用android.text.Spanned; android.text.SpannableString; android.text.SpannableStringBuilder; 和 and ...

  8. SpannableString 记录(转)

    引用 http://blog.csdn.net/rockcoding/article/details/7231756 TextView是用来显示文本的,有时需要给TextView中的个别字设置为超链接 ...

  9. Android TextView结合SpannableString使用

    super.onCreate(savedInstanceState); TextView txtInfo = new TextView(this); SpannableString ss = new ...

  10. SpannableStringBuilder 和 SpannableString

    EditText:         通常用于显示文字,但有时候也需要在文字中夹杂一些图片,比如QQ中就可以使用表情图片,又比如需要的文字高亮显示等等,如何在android中也做到这样呢? 记得andr ...

随机推荐

  1. PC端页面同比例缩放

    <meta name="viewport" content="width=1202"> //这行代码可以使PC端页面同比例缩放,不至于变形

  2. 探寻main函数的“标准”写法,以及获取main函数的参数、返回值

    main函数表示法        很多同学在初学C或者C++时,都见过各种各样的main函数表示法: main(){/*...*/} void main(){/*...*/} int main(){/ ...

  3. studying Bitcoin

    https://github.com/bitcoinbook/bitcoinbook/blob/develop/book.asciidoc https://github.com/bitcoin/bip ...

  4. tcp拥堵算法

    http://m.blog.csdn.net/article/details?id=6739189

  5. 【Spring】Spring Session的简单搭建与源码阅读

    搭建一个简单的Spring Session例子 引入依赖包 <dependencies> <dependency> <groupId>org.springframe ...

  6. DIOCP开源项目-DIOCP3的LoadRunner11测试报告

    昨天有个多年的群友(B3.Locet)用LoadRunner11对DIOCP3做压力测试,说测试的时候出现了大量的10053,10054的报告.昨天晚上下载了个LoadRunner11, 今天捣鼓了下 ...

  7. 【Bootloader】bootloader启动过程分析

    Boot Loader启动过程分析 一.    Boot Loader的概念和功能 1.嵌入式Linux软件结构与分布在一般情况下嵌入式Linux系统中的软件主要分为以下及部分: (1)引导加载程序: ...

  8. System.in的用法

    方法1 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));Scanner scanner=new Sca ...

  9. linux磁盘 分区 物理卷 卷组 逻辑卷 文件系统加载点操作案例

    转自:truemylife.linux磁盘 分区 物理卷 卷组 逻辑卷 文件系统加载点操作案例 基本概念: 磁盘.分区.物理卷[物理部分] 卷组[中间部分] 逻辑卷.文件系统[虚拟化后可控制部分] 磁 ...

  10. C#学习笔记(17)——C#中接口的作用

    说明(2017-7-17 23:50:48): 原文: 接口的作用 接口的作用(C#)(另一篇) C#接口是一个让很多初学C#者容易迷糊的东西,用起来好像很简单,定义接口,里面包含方法,但没有方法具体 ...