1、SpannableString、SpannableStringBuilder与String的关系首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉,等等。所以,总而言之,SpannableString、SpannableStringBuilder与String一样, 首先也是传字符串,但SpannableString、SpannableStringBuilder可以对这些字符串添加额外的样式信息,但String则不行。注意:如果这些额外信息能被所用的方式支持,比如将SpannableString传给TextView;也有对这些额外信息不支持的,比如前一章讲到的Canvas绘制文字,对于不支持的情况,SpannableString和SpannableStringBuilder就是退化为String类型,直接显示原来的String字符串,而不会再显示这些附加的额外信息。2、SpannableString与SpannableStringBuilder区别它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String;SpannableString与SpannableStringBuilder使用_setSpan3、SetSpan()void setSpan (Object what, int start, int end, int flags)函数意义:给SpannableString或SpannableStringBuilder特定范围的字符串设定Span样式,可以设置多个(比如同时加上下划线和删除线等),Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式。参数说明:object what :对应的各种Span,后面会提到;int start:开始应用指定Span的位置,索引从0开始int end:结束应用指定Span的位置,特效并不包括这个位置。比如如果这里数为3(即第4个字符),第4个字符不会有任何特效。从下面的例子也可以看出来。int flags:取值有如下四个Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式Spannable.SPAN_EXCLUSIVE_INCLUSIVE :前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式Spannable.SPAN_INCLUSIVE_EXCLUSIVE :前面包括,后面不包括。Spannable.SPAN_INCLUSIVE_INCLUSIVE :前后都包括。下面写了个小demo,先看一下效果图:

SpannableString与SpannableStringBuilder使用_setSpan_02

SpannableString与SpannableStringBuilder使用_setSpan_03

  1 public class MainActivity extends Activity implements OnClickListener {  2     private TextView tv;  3     private Button underline_btn;  4     private Button strike_btn;  5     private Button style_btn;  6     private Button font_btn;  7     private Button color_btn1;  8     private Button color_btn2;  9     private Button url_btn; 10     private Button p_w_picpath_btn; 11     private Button maskfilte_btn; 12     private Button Rasterizer_btn; 13     private Button spannablestringbuilder; 14     @Override 15     protected void onCreate(Bundle savedInstanceState) { 16         super.onCreate(savedInstanceState); 17         setContentView(R.layout.activity_main); 18         tv = (TextView) this.findViewById(R.id.tv); 19         underline_btn = (Button) this.findViewById(R.id.underline_btn); 20         strike_btn = (Button) this.findViewById(R.id.strike_btn); 21         style_btn = (Button) this.findViewById(R.id.style_btn); 22         font_btn = (Button) this.findViewById(R.id.font_btn); 23         color_btn1 = (Button) this.findViewById(R.id.color_btn1); 24         color_btn2 = (Button) this.findViewById(R.id.color_btn2); 25         url_btn = (Button) this.findViewById(R.id.url_btn); 26         p_w_picpath_btn = (Button) this.findViewById(R.id.p_w_picpath_btn); 27         maskfilte_btn = (Button) this.findViewById(R.id.maskfilte_btn); 28         Rasterizer_btn = (Button) this.findViewById(R.id.Rasterizer_btn); 29         spannablestringbuilder = (Button) this.findViewById(R.id.spannablestringbuilder); 30   31         underline_btn.setOnClickListener(this); 32         strike_btn.setOnClickListener(this); 33         style_btn.setOnClickListener(this); 34         font_btn.setOnClickListener(this); 35         color_btn1.setOnClickListener(this); 36         color_btn2.setOnClickListener(this); 37         url_btn.setOnClickListener(this); 38         p_w_picpath_btn.setOnClickListener(this); 39         maskfilte_btn.setOnClickListener(this); 40         Rasterizer_btn.setOnClickListener(this); 41         spannablestringbuilder.setOnClickListener(this); 42   43     } 44   45     @Override 46     public void onClick(View v) { 47         switch (v.getId()) { 48         case R.id.underline_btn: 49             addUnderLineSpan(); 50             break; 51         case R.id.strike_btn: 52             addStrikeSpan(); 53             break; 54         case R.id.style_btn: 55             addStyleSpan(); 56             break; 57         case R.id.font_btn: 58             addFontSpan(); 59             break; 60         case R.id.color_btn1: 61             addForeColorSpan(); 62             break; 63         case R.id.color_btn2: 64             addBackColorSpan(); 65             break; 66         case R.id.url_btn: 67             addUrlSpan(); 68             break; 69         case R.id.p_w_picpath_btn: 70             addImageSpan(); 71             break; 72         case R.id.maskfilte_btn: 73             addmaskfilteSpan(); 74             break; 75         case R.id.Rasterizer_btn: 76             addRasterizerSpan(); 77             break; 78         case R.id.spannablestringbuilder: 79             addspannablestringbuilderSpan(); 80             break; 81         } 82     } 83     /** 84      * spannablestringbuilder 85      */ 86     private void addspannablestringbuilderSpan() { 87         SpannableStringBuilder ss=new SpannableStringBuilder("红色超链接斜体删除线绿色下划线图片:."); 
 88            //用颜色标记文本 89         ss.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, 
 90                 //setSpan时需要指定的 flag,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括). 91                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 92         //用超链接标记文本 93         ss.setSpan(new URLSpan("tel:4155551212"), 2, 5, 
 94                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 95         //用样式标记文本(斜体) 96         ss.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 7, 
 97                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 98         //用删除线标记文本 99         ss.setSpan(new StrikethroughSpan(), 7, 10, 
100                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);101         //用下划线标记文本102         ss.setSpan(new UnderlineSpan(), 10, 16, 
103                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);104         //用颜色标记105         ss.setSpan(new ForegroundColorSpan(Color.GREEN), 10, 12, 
106                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);107         //获取Drawable资源108         Drawable d = getResources().getDrawable(R.drawable.ic_launcher); 
109         d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());110         //创建ImageSpan111         ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);112         //用ImageSpan替换文本113         ss.setSpan(span, 18, 19, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); 
114         tv.append("\n");115         tv.setText(ss);116         tv.setMovementMethod(LinkMovementMethod.getInstance()); //实现文本的滚动 117     }118  119     /*120      * Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式121      * Spannable.SPAN_EXCLUSIVE_INCLUSIVE :前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式122      * Spannable.SPAN_INCLUSIVE_EXCLUSIVE :前面包括,后面不包括。123      * Spannable.SPAN_INCLUSIVE_INCLUSIVE :前后都包括。124      */125     /**126      * 光栅效果127      */128     private void addRasterizerSpan() {129         SpannableString spanText = new SpannableString("StrikethroughSpan");130         spanText.setSpan(new StrikethroughSpan(), 0, 7, Spannable.131         SPAN_INCLUSIVE_EXCLUSIVE);132         tv.append("\n");133         tv.append(spanText);134          135     }136     /**137      * 修饰效果138      */139     private void addmaskfilteSpan() {140         SpannableString spanText = new SpannableString("benzlocke6666666");141         int length = spanText.length();142         //模糊(BlurMaskFilter)143         MaskFilterSpan maskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(3, Blur.OUTER));144         spanText.setSpan(maskFilterSpan, 0, length - 10, Spannable.145         SPAN_INCLUSIVE_EXCLUSIVE);146         //浮雕(EmbossMaskFilter)147         maskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{1,1,3}, 1.5f, 8, 3));148         spanText.setSpan(maskFilterSpan, length - 10, length, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);149         tv.append("\n");150         tv.append(spanText);151          152     }153  154     /**155      * 超链接156      */157     private void addUrlSpan() {158         SpannableString spanString = new SpannableString("超链接");159         URLSpan span = new URLSpan("tel:0123456789");160         spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);161         tv.append("\n");162         tv.append(spanString);163          164         tv.setMovementMethod(LinkMovementMethod.getInstance());165     }166  167     /**168      * 文字背景颜色169      */170     private void addBackColorSpan() {171         SpannableString spanString = new SpannableString("文字背景颜色");172         BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW);173         spanString.setSpan(span, 0, 6, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);174         tv.append("\n");175         tv.append(spanString);176     }177  178     /**179      * 文字颜色180      */181     private void addForeColorSpan() {182         SpannableString spanString = new SpannableString("文字颜色");183         ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE);184         spanString.setSpan(span, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);185         tv.append("\n");186         tv.append(spanString);187     }188  189     /**190      * 字体大小191      */192     private void addFontSpan() {193         SpannableString spanString = new SpannableString("36号字体");194         AbsoluteSizeSpan span = new AbsoluteSizeSpan(36);195         spanString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);196         tv.append("\n");197         tv.append(spanString);198     }199  200     /**201      * 粗体,斜体202      */203     private void addStyleSpan() {204         SpannableString spanString = new SpannableString("ABCDEF");205         StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);206         spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);207         tv.append("\n");208         tv.append(spanString);209     }210  211     /**212      * 删除线213      */214     private void addStrikeSpan() {215         SpannableString spanString = new SpannableString("删除线");216         StrikethroughSpan span = new StrikethroughSpan();217         spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);218         tv.append("\n");219         tv.append(spanString);220     }221  222     /**223      * 下划线224      */225     private void addUnderLineSpan() {226         SpannableString spanString = new SpannableString("下划线");227         UnderlineSpan span = new UnderlineSpan();228         spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);229         tv.append("\n");230         tv.append(spanString);231     }232  233     /**234      * 图片235      */236     private void addImageSpan() {237         SpannableString spanString = new SpannableString(" ");238         Drawable d = getResources().getDrawable(R.drawable.ic_launcher);239         d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());240         ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);241         spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);242         tv.append("\n");243         tv.append(spanString);244     }245 }

SpannableString与SpannableStringBuilder使用_setSpan_03