Textview设置不同颜色,下划线,加粗,超链接(SpannableString)

作为android移动开发者,当需要给TextView设置字体显示样式时(比如设置颜色,字号,加粗等),一般可以在布局xml文件中设置,或者在代码中动态设置;但如果有需求是这样的,比如:

项目需求:后台返回的String数据是“4月13日健康状态:以上结论依据过去24小时内620次心率、115次血压、373次血氧数据得出;每天中午13:00出具结论,统计24小时内数据。”要求在TextView的显示格式为“4月13日健康状态:以上结论依据过去24小时内620次心率、115次血压、373次血氧数据得出;每天中午13:00出具结论,统计24小时内数据。”这时String就不太好用了,当然你可以说用两个TextView来显示,这里我们就不谈这种方式了。下面我们谈谈SpannableString。

1.简介

对于给Textview设置不同颜色,就不得不提SpannableString,当然给textview设置不同的字体颜色也可以通过加HTML标签来实现,但是有SpannableString的存在,为啥不用呢.

先简单的介绍一下SpannableString,SpannableStringBuilder.

SpannableString和SpannableStringBuilder

首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,

能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、加背景色、改变字体

颜色、用图片把指定的文字给替换掉,加超链接等等。总而言之,SpannableString和SpannableStringBuilder和string差不多,但是不能给字符串设置

不同的样式.

注意:如果这些额外信息能被所用的方式支持,比如将SpannableString传给TextView;也有对这些额外信息不支持的,比如自定义view中Canvas绘制

文字,对于不支持的情况,SpannableString和SpannableStringBuilder就是退化为String类型,直接显示原来的String字符串,而不会再显示这些附加的

额外信息。

当然,SpannableString和SpannableStringBuilder也是存在区别的,它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个

String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方

法来拼接多个String.

 

?
1
2
3
4
5
6
//使用SpannableString,必须一次传入,构造完成 
SpannableString word = new SpannableString( "疯狂的dialog" ); 
//使用SpannableStringBuilder,可以使用append()再添加 
SpannableStringBuilder bWord = new SpannableStringBuilder(); 
bWord.append( "疯狂的" ); 
bWord.append( "dialog" ); 
由于 SpannableString和SpannableStringBuilder 都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。

 

2.具体实现

给文本设置不同的样式是通过setSpan()方法来实现的,其中的具体样式根据参数来定义.

 

?
1
setSpan (Object what, int start, int end, int flags)
参数说明:1.Object what :给文本设置不同的样式(大小,粗细,颜色等等)

 

2.int start:设置span的开始位置,默认索引从0开始.

3.int end:设置span结束的位置,但是不包含这个位置

4.int flags:取值有如下四个
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE :前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
Spannable.SPAN_INCLUSIVE_EXCLUSIVE :前面包括,后面不包括。
Spannable.SPAN_INCLUSIVE_INCLUSIVE :前后都包括。
设置不同的样式的具体实现就直接通过demo的代码来实现了,里面有注解就不一一解释了.

 

?
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
public class MainActivity extends Activity {
TextView mTextView = null ;
SpannableString msp = null ;
 
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
 
mTextView = (TextView)findViewById(R.id.tv);
 
//创建一个 SpannableString对象
msp = new SpannableString( "字体测试字体大小一半两倍前景色背景色正常粗体斜体粗斜体下划线删除线x8x3电话邮件网站短信彩信地图X轴综合/bot" );
 
//设置字体(default,default-bold,monospace,serif,sans-serif)
msp.setSpan( new TypefaceSpan( "monospace" ), 0 , 2 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
msp.setSpan( new TypefaceSpan( "serif" ), 2 , 4 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//设置字体大小(绝对值,单位:像素)
msp.setSpan( new AbsoluteSizeSpan( 20 ), 4 , 6 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
msp.setSpan( new AbsoluteSizeSpan( 20 , true ), 6 , 8 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第二个参数boolean dip,如果为true,表示前面的字体大小单位为dip,否则为像素,同上。
 
//设置字体大小(相对值,单位:像素) 参数表示为默认字体大小的多少倍
msp.setSpan( new RelativeSizeSpan( 0 .5f), 8 , 10 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //0.5f表示默认字体大小的一半
msp.setSpan( new RelativeSizeSpan( 2 .0f), 10 , 12 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默认字体大小的两倍
 
//设置字体前景色
msp.setSpan( new ForegroundColorSpan(Color.MAGENTA), 12 , 15 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //设置前景色为洋红色
 
//设置字体背景色
msp.setSpan( new BackgroundColorSpan(Color.CYAN), 15 , 18 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //设置背景色为青色
 
//设置字体样式正常,粗体,斜体,粗斜体
msp.setSpan( new StyleSpan(android.graphics.Typeface.NORMAL), 18 , 20 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //正常
msp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD), 20 , 22 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗体
msp.setSpan( new StyleSpan(android.graphics.Typeface.ITALIC), 22 , 24 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //斜体
msp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 24 , 27 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //粗斜体
 
//设置下划线
msp.setSpan( new UnderlineSpan(), 27 , 30 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//设置删除线
msp.setSpan( new StrikethroughSpan(), 30 , 33 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//设置上下标
msp.setSpan( new SubscriptSpan(), 34 , 35 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //下标
msp.setSpan( new SuperscriptSpan(), 36 , 37 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //上标
 
//超级链接(需要添加setMovementMethod方法附加响应)
msp.setSpan( new URLSpan( "tel:10086" ), 37 , 39 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //电话
msp.setSpan( new URLSpan( "123456789@qq.com" ), 39 , 41 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //邮件
msp.setSpan( new URLSpan( "https://www.baidu.com " ), 41 , 43 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //网络
msp.setSpan( new URLSpan( "sms:10086" ), 43 , 45 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //短信 使用sms:或者smsto: 
msp.setSpan( new URLSpan( "mms:10086" ), 45 , 47 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //彩信 使用mms:或者mmsto:
msp.setSpan( new URLSpan( "geo:38.899533,-77.036476" ), 47 , 49 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //地图
//设置字体大小(相对值,单位:像素) 参数表示为默认字体宽度的多少倍
msp.setSpan( new ScaleXSpan( 2 .0f), 49 , 51 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //2.0f表示默认字体宽度的两倍,即X轴方向放大为默认字体的两倍,而高度不变
//设置字体(依次包括字体名称,字体大小,字体样式,字体颜色,链接颜色)
ColorStateList csllink = null ;
ColorStateList csl = null ;
// XmlResourceParser xppcolor=getResources().getXml (R.color.color);
// try {
// csl= ColorStateList.createFromXml(getResources(),xppcolor);
// }catch(XmlPullParserException e){
// e.printStackTrace();
// }catch(IOException e){
// e.printStackTrace();
// }
 
// XmlResourceParser xpplinkcolor=getResources().getXml(R.color.linkcolor);
// try {
// csllink= ColorStateList.createFromXml(getResources(),xpplinkcolor);
// }catch(XmlPullParserException e){
// e.printStackTrace();
// }catch(IOException e){
// e.printStackTrace();
// }
msp.setSpan( new TextAppearanceSpan( "monospace" ,android.graphics.Typeface.BOLD_ITALIC, 30 , csl, csllink), 51 ,
?
1
2
3
4
5
6
7
8
9
10
11
12
13
53 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
//设置项目符号
msp.setSpan( new BulletSpan(android.text.style.BulletSpan.STANDARD_GAP_WIDTH,Color.GREEN),
0 ,msp.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //第一个参数表示项目符号占用的宽度,第二个参数为项目符号的颜色
//设置图片
// Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
// drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
// msp.setSpan(new ImageSpan(drawable), 53, 57, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.setText(msp);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值