Android----SpannableString

1、背景介绍

在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的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。

2、使用方法

当要显示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。

3、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,然后做相应的操作

4、权衡选择

个人认为软件开发中最常见的问题不是某个技巧怎么使用的问题,而是何时该使用何技巧的问题,因为实现同一个目标可能有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中实现图文混排的效果

下面是一些实例代码

  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. * 文字背景颜色 
  14. */  
  15. private void addBackColorSpan() {  
  16.     SpannableString spanString = new SpannableString("颜色2");  
  17.     BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);  
  18.     spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  19.     tv.append(spanString);  
  20. }  
  21.   
  22.   
  23. /** 
  24. * 文字颜色 
  25. */  
  26. private void addForeColorSpan() {  
  27.     SpannableString spanString = new SpannableString("颜色1");  
  28.     ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);  
  29.     spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  30.     tv.append(spanString);  
  31. }  
  32.   
  33.   
  34. /** 
  35. * 字体大小 
  36. */  
  37. private void addFontSpan() {  
  38.     SpannableString spanString = new SpannableString("36号字体");  
  39.     AbsoluteSizeSpan span = new AbsoluteSizeSpan(36);  
  40.     spanString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  41.     tv.append(spanString);  
  42. }  
  43.   
  44.   
  45. /** 
  46. * 粗体,斜体 
  47. */  
  48. private void addStyleSpan() {  
  49.     SpannableString spanString = new SpannableString("BIBI");  
  50.     StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);  
  51.     spanString.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  52.     tv.append(spanString);  
  53. }  
  54.   
  55.   
  56. /** 
  57. * 删除线 
  58. */  
  59. private void addStrikeSpan() {  
  60.     SpannableString spanString = new SpannableString("删除线");  
  61.     StrikethroughSpan span = new StrikethroughSpan();  
  62.     spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  63.     tv.append(spanString);  
  64. }  
  65.   
  66. /** 
  67. * 下划线 
  68. */  
  69. private void addUnderLineSpan() {  
  70.     SpannableString spanString = new SpannableString("下划线");  
  71.     UnderlineSpan span = new UnderlineSpan();  
  72.     spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  73.     tv.append(spanString);  
  74. }  
  75.   
  76.   
  77.   
  78. /** 
  79. * 图片 
  80. */  
  81. private void addImageSpan() {  
  82.     SpannableString spanString = new SpannableString(" ");  
  83.     Drawable d = getResources().getDrawable(R.drawable.ic_launcher);  
  84.     d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());  
  85.     ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);  
  86.     spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  87.     tv.append(spanString);  
  88. }  
  89. }  

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 23:39:38

Android----SpannableString的相关文章

Android SpannableString浅析

引言 在应用程序开发过程经常需要对文本进行处理,比如说对一段描述文字的其中一段加入点击事件,或者对其设置不一样的前景色,有什么方法可以实现要求的功能呐? 需求样例 比如我们需要实现如下图所示的功能,将文本:#重磅消息#近日谷歌放出Android N的第二个开发者预览版(Developer Preview) 处理成第二种或者第三种的形式. 实现方案 根据上图,我们可以采用如下的方法来实现上诉要求的效果. 方案1 比如显示效果二你可以能会说,我们可以采用三个TextView来实现,第一个TextVi

Android - SpannableString或SpannableStringBuilder以及string.xml文件中的整型和string型代替

背景介绍 在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的LockScreen上面的时间和充电信息.对于类似的情况,可能第一反应就是用不同的多个TextView来实现,对于每个TextView设置不同的字体风格以满足需求. 这里推荐的做法是使用android.text.*;和 android.text.style.*;下面的组件来实现RichText:也即在同一个TextView中设置不同的字体风格.对于某些应用,比如文本编辑,记事本,彩信,短信等地方,还必须使用这些组件才能达到

Android SpannableString 基本用法

以下介绍SpannableString 对文字的一些特别处理:比如字体,颜色,下划线,链接和点击事件. 先看效果: 布局代码就不贴了,很简单就是3个TextView.现在看MainActivity中的代码实现: private TextView mTvContent1; private TextView mTvContent2; private TextView mTvContent3; private String contentStr1 = "点击事件,下划线,字体颜色"; pri

Android项目实战(一): SpannableString与SpannableStringBuilder

原文:Android项目实战(一): SpannableString与SpannableStringBuilder 前言: 曾经在一些APP中的一些类似“帮助”“关于”的界面看过一行文字显示不同的颜色的效果,如下效果: 本软件是一款高.大.上的社区类软件. 一般来说,这应该是由一个TextView来显示的,但是自己又不会实现,怎么办呢,只能一个颜色搞一个TextView连起来,形成上面的效果. 但是那样实现的话都显得太低级了.直到我偶然的知道了SpannableString 类.网上学习了一下,

【转载】 SpannableString与SpannableStringBuilder

一.概述 1.SpannableString.SpannableStringBuilder与String的关系 首 先SpannableString.SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在 于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原 来String上加下划线.加背景色.改变字体颜色.用图片把指定的文字给替换掉,等等.所以,总

Android Html解析

在前一篇Android SpannableString浅析中我们采用html实现了文本处理的效果.当时设置部分的代码如下: private void setText() { String originText = "#重磅消息#近日谷歌放出Android N的第二个开发者预览版(Developer Preview)"; String effect1 = "<font color='#FF0000'>#重磅消息#</font> <br> 近日

SpannableString与SpannableStringBuilder

一.概述 1.SpannableString.SpannableStringBuilder与String的关系 首先SpannableString.SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线.加背景色.改变字体颜色.用图片把指定的文字给替换掉,等等.所以,总而言之

Android开发之SpannableString详解

在实际的应用开发过程中经常会遇到,在文本的不同部分显示一些不同的字体风格的信息如:文本的字体.大小.颜色.样式.以及超级链接等.一般情况下,TextView中的文本都是一个样式,对于类似的情况,可以借助SpannableString或SpannableStringBuilder对象来实现以上设置. SpannableString与SpannableStringBuilder都可以将某段文本设置成一个Span,在Android中,Span表示一段文本的效果,例如,链接形式.图像.带背景的文本等.只

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

在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及超级链接等属性呢?下面我们通过SpannableString的具体实例操作来演示一下. res-layout-main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and

[android篇]textview中片段响应点击事件(SpannableString)

项目需求 点击textView中的一小段文字,弹一个dialog框 失败解决方案 刚开始是用了两个textView水平布局,可想而知,当第一个textView快占满一行,还未换行时,第二个textView很可能出现换行排版问题 用spannableString的问题 小段文字有下划线 点击textView中的小段文字时,系统会当做url处理,给点击部分的text加一个蓝色的背景 解决方案 public class TouchableSpan extends ClickableSpan { pri