我们之前说过了我们想实现在TextView组件之中,可以显示URL、Email等特殊信息,这些信息点击可以实现跳转,真正意义上的超链接
要实现上面的需求就要SpannableString这个类。
因为Spannable等最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。
SpannableString:特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、超链接跳转、加背景色、改变字体颜色、用图片把指定的文字给替换掉,等等。
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 :前后都包括。
1.首先我们实现跳转,这里是实现跳转实现Activity,核心代码如下:
String text = "显示Activity1"; SpannableString spannableString = new SpannableString(text); spannableString.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Intent intent = new Intent(MainActivity.this, Activity1.class); startActivity(intent); } },0,text.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //设置SpannableString对象设置两个TextView组件内容 textview.setText(spannableString); //单击链接时凡是要执行的动作,都必须设置MovementMethod对象 textview.setMovementMethod(LinkMovementMethod.getInstance());
2.字体样式设置
在前面的一个小示例,大家应该也可以看出,要应用一个Span总共分三步:
1、构造String
2、构造Span
3、利用SetSpan()对指定范围的String应用这个Span
(1)字体颜色设置(ForegroundColorSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); //再构造一个改变字体颜色的Span ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE); //将这个Span应用于指定范围的字体 spanString.setSpan(span, 1, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //设置给EditText显示出来 editText.setText(spanString);
(2)字体背景颜色(BackgroundColorSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW); spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
(3)字体大小(AbsoluteSizeSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); AbsoluteSizeSpan span = new AbsoluteSizeSpan(16); spanString.setSpan(span, 2, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE); editText.setText(spanString);
(4)粗体、斜体(StyleSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC); spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
(5)删除线(StrikethroughSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); StrikethroughSpan span = new StrikethroughSpan(); spanString.setSpan(span, 2, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
(6)下划线(UnderlineSpan)
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); UnderlineSpan span = new UnderlineSpan(); spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
(7)图片置换(ImageSpan)
ImagSpan有很多构造函数,一般是通过传入Drawableg来构造,详细的构造说明看这里:http://developer.android.com/reference/android/text/style/ImageSpan.html
SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 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, 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); editText.setText(spanString);
这个函数的不同之处在于,前几都是在原来文字的基础上加上特效,而这里却是利用图片将文字替换。如果遇到不支持显示图片的函数,比如前一篇中的canvas绘图。就会退化成String,即以原来的String字符串来显示。