SpannableString与SpannableStringBuilder使用【原创】

SpannableString与SpannableStringBuilder使用【原创】



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;

无标题

3、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,先看一下效果图:

lADOAnId_M0FAM0C0A_720_1280

代码如下所示:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值