TextView之SpannableStringBuilder使用总结

最近项目中碰到一个TextView的显示问题,想了各种办法之后,最后还是用SpannableStringBuilder解决的。这篇文章就记录下我的问题的解决过程,同时总结下SpannableStringBuilderTextView中的不同用法。

背景

项目中GridView有两列,每个Item视图都有一个TextView(设置了最大显示行数),项目业务要求每列的TextView展示高度相同,但是因为显示的文本你不知道有多少行,所以在布局的时候不能设置固定高度,而是设置为wrap_content,所以为了保证两列的TextView高度一致,只需要保证他们展示内容的行数一致就行。

而上面的问题只需要在内容行数达不到最大显示行数时,为其手动补齐行数即可。

这里有个问题就是如何计算当前要展示的文本在此TextView中能展示多少行,这个地方直接通过textView.getLineCount()是不行的,我是通过StaticLayout计算当前文本能显示的行数,对于StaticLayout的使用这篇文章就不介绍了,不会的同学可以去google下,后面的文章我会专门介绍StaticLayout的使用

有了上面的解决方法之后,我在行数不足时我手动添加了换行符\n补齐行数,但是运行之后,发现达不到效果,因为虽然手动换行,但是通过换行符\n换行之后的高度达不到实际文本行显示的高度,因此这种方式还是没法保证两边TextView高度一致。

既然单纯的换行无法达到我们想要的效果,那我就在换行之后再添加几个文字,有了这几个文字就可以让其真正达到多行文本的效果了。但是多的这几个字会显示在界面上,所以我们只需要让这几个文字不显示出来或者让这几个文字完全透明即可。

TextView的部分文本设置为透明色,最后查询之后发现SpannableStringBuilder可以实现这样的效果,下面我就总结下SpannableStringBuilder结合TextView的使用方法。

SpannableStringBuilder使用总结

我们来看下SpannableStringBuilder的官方介绍

This is the class for text whose content and markup can both be changed

通过上面的介绍可以看出SpannableStringBuilder是一个内容和标记都可以更改的类,它其实是CharSequence的子类。

SpannableStringBuilder使用效果

文本高亮

使用ForegroundColorSpanTextView的部分文本添加指定颜色,使这部分文本高亮显示

1
2
3
4
5
6
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//高亮的开始位置
builder.append("文本高亮");
int end = builder.length();//高亮的结束位置
builder.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

  • ForegroundColorSpan代表设置文本高亮的颜色
  • Spanned.SPAN_INCLUSIVE_EXCLUSIVE这个常量表示高亮开始位置但不包含结束位置的字符,还有几个类似的常量,这几个常量与Stirng.subString()方法的参数代表的意思是类似的。
  • 上面我的解决办法中需要文本完全透明,只需要将高亮的颜色设置为100%透明即可

URL超链接效果

使用URLSpanTextView的部分文本添加超链接效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//URL文本开始位置
builder.append("URL连接");
int end = builder.length();//URL文本结束位置
builder.setSpan(new URLSpan("www.baidu.com") {
@Override
public void onClick(View widget) {
//URLSpan点击响应
UIUtil.showToast(context, "URLSpan点击");
}
}, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);
//必须设置下面的方法,否则URLSpan点击事件无法响应
mTextView.setMovementMethod(LinkMovementMethod.getInstance());

  • 使用URLSpan即可将TextView的部分文本设置为超链接显示样式,同时还可以实现点击响应,但是必须调用TextView.setMovementMethod(LinkMovementMethod.getInstance());点击响应才会有效

设置文本背景色

使用BackgroundColorSpanTextView的部分文本添加背景色

1
2
3
4
5
6
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置背景色的开始位置
builder.append("设置背景色");
int end = builder.length();//设置背景色的结束位置
builder.setSpan(new BackgroundColorSpan(Color.BLUE), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

  • BackgroundColorSpan可以将TextView的部分文本添加背景色,与ForegroundColorSpan的使用方式相同,只需要设置颜色即可

添加文本下划线

使用UnderlineSpanTextView的部分文本添加下划线

1
2
3
4
5
6
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置下划线的开始位置
builder.append("下划线文本");
int end = builder.length();//设置下划线的结束位置
builder.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

文本添加删除线

使用StrikethroughSpanTextView的部分文本添加删除线

1
2
3
4
5
6
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置删除线的开始位置
builder.append("删除线文本");
int end = builder.length();//设置删除线的结束位置
builder.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

图片替换文本

使用ImageSpanTextView的部分文本替换为图片

1
2
3
4
5
6
7
8
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//替换为图片的开始位置
builder.append("图片替换文本");
int end = builder.length();//替换为图片的结束位置
Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0, 0, 50, 50);//设置图片为50px大小
builder.setSpan(new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

设置部分粗体

使用StyleSpanTextView的部分文本设置为粗体

1
2
3
4
5
6
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置粗体的开始位置
builder.append("粗体文本");
int end = builder.length();//设置粗体的结束位置
builder.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

为任意文本添加点击响应

使用ClickableSpanTextView的任意文本添加点击响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置删除线的开始位置
builder.append("单击响应文本");
int end = builder.length();//设置删除线的结束位置
builder.setSpan(new ClickableSpan() {//将任意文本设置为可点击
@Override
public void onClick(View widget) {
UIUtil.showToast(StyleTextViewActivity.this, "ClickableSpan");
}
@Override
public void updateDrawState(TextPaint ds) {
//此方法的默认实现会出现下划线效果,去掉其默认实现
}
}, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());

组合使用各效果

1
2
3
4
5
6
7
SpannableStringBuilder builder = new SpannableStringBuilder("普通文本");
int start = builder.length();//设置组合使用的开始位置
builder.append("组合使用");
int end = builder.length();//设置组合使用的结束位置
builder.setSpan(new ForegroundColorSpan(Color.WHITE), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
builder.setSpan(new BackgroundColorSpan(Color.RED), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTextView.setText(builder);

上面这些就是SpannableStringBuilder结合TextView的一些使用方法,其实使用起来还是很简单的。

具体使用示例代码请参考:https://github.com/huyongli/AndroidDemo

write by laohu
2016年11月5日21:45:48


原创文章,本文采用知识共享署名 2.5(中国大陆许可协议)进行许可,欢迎转载,但转载请注明来自ittiger.cn,并保证转载后文章内容的完整性。本人(laohu)保留所有版权相关权利。



评论