作为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"
);
|
2.具体实现
给文本设置不同的样式是通过setSpan()方法来实现的,其中的具体样式根据参数来定义.
1
|
setSpan (Object what,
int
start,
int
end,
int
flags)
|
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());
}
}
|