android 使用SpannableString与SpannableStringBuilder

在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的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所在的端点
这里理解起来就好像数学中定义区间,开区间还是闭区间一样的。这里要重点说明下关于参数0,有很多时候,如果设置了上述的参数,那么Span会从start应用到Text结尾,而不是在start和end二者之间,这个时候就需要使用Flag 0。

 

在Android中TextView和EditText是用来显示文本的,有时需要给TextView中的个别字设置为超链接,或者设置个别字的颜色、字体等,那就需要用到Spannable对象,可以借助Spannable对象实现以上设置。

废话少说,直接上代码:

package com.qzhousoft.SpannableDemo.ui;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
import android.widget.TextView;

/**
* <Spannable使用示例> 
* @author 王乾州
*/
public class main extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

TextView spannableTextView = (TextView)this.findViewById(R.id.tv);

/**
* 创建一个 SpannableString对象
*/
SpannableString sp = new SpannableString(“谷歌超链接、高亮显示、高亮1、高亮2、斜体、下划线.”);

/**
* 设置超链接
*/
sp.setSpan(new URLSpan(“http://www.google.com”), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

/**
* 设置高亮样式一
*/
sp.setSpan(new BackgroundColorSpan(Color.RED), 11, 14, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

/**
* 设置高亮样式二
*/
sp.setSpan(new ForegroundColorSpan(Color.YELLOW), 15, 18, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

/**
* 设置斜体
*/
sp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 19, 21, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

/**
* 设置下划线
*/
sp.setSpan(new UnderlineSpan(), 22, 25, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

/**
* SpannableString对象设置给TextView
*/
spannableTextView.setText(sp);

/**
* 设置TextView中的超链接可点击
*/
spannableTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
}

注意点:

当我们文字中有了超链接时,一般我们必须有网络权限,但是在这里大家不用添加网络权限也可以访问超链接哦。。。

    * spannableTextView.setMovementMethod(LinkMovementMethod.getInstance());这句很重要,如果没有这句,超链接是不可点击的。

 

如果我们文字中包含html标签那我们该如何展示哪,有一个很好的静态方法:

Html.fromHtml()

myTextView.setText(Html.fromHtml(“<font color=\”#330099\”>测试…</font>”));

myTextView.setMovementMethod(LinkMovementMethod.getInstance()); // 如果标签里有链接要加上这句,否则链接无效撒。。。

猜你喜欢

转载自narutolufi.iteye.com/blog/1948635