Android中SpannableString、SpannableStringBuilder与String的关系

SpannableString、SpannableStringBuilder与String的关系

1.1 概述

SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉,等等。所以,总而言之,SpannableString、SpannableStringBuilder与String一样, 首先也是传字符串,但SpannableString、SpannableStringBuilder可以对这些字符串添加额外的样式信息,但String则不行。

它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String。

功能 String SpannableString SpannableStringBuilder
存储字符串
通过setSpan()能给存储的字符串添加各种样式(Span),比如颜色背景等
创建之后是否可以更改其内容并跟随变化

1.2 setSpan()方法介绍

void setSpan (Object what, int start, int end, int flags)

Object what 对应各种Span
int start 开始应用指定Span的位置,索引从0开始
int end 结束应用指定Span的位置,特效并不包括这个位置
int flags 指定范围前后输入新的字符时,会不会应用效果

flags参数介绍

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
Spannable.SPAN_EXCLUSIVE_INCLUSIVE 前面不包括,后面包括,即仅在范围字符的后面插入新字符时会应用新样式
Spannable.SPAN_INCLUSIVE_EXCLUSIVE 前面包括,后面不包括
Spannable.SPAN_INCLUSIVE_INCLUSIVE 前后都包括

1.3 Span汇总

用途 Span
设置字体颜色 ForegroundColorSpan
设置字体背景颜色 BackgroundColorSpan
设置字体大小 AbsoluteSizeSpan
设置字体为粗体、斜体 StyleSpan
设置字体删除线 StrikethroughSpan
设置字体下划线 UnderlineSpan
将文字替换成图片 ImageSpan
点击文字可以打开一个URL URLSpan
文字可点击 ClickableSpan
1.3.1 设置字体颜色 ForegroundColorSpan
String str = "Hello World!";
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent));
ssb.setSpan(foregroundColorSpan, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTv.setText(ssb);

Android中SpannableString、SpannableStringBuilder与String的关系_第1张图片

1.3.2 点击文字可以打开一个URL URLSpan
String str = "点击百度!";
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
URLSpan urlSpan = new URLSpan("https://www.baidu.com/");
ssb.setSpan(urlSpan, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTv.setMovementMethod(LinkMovementMethod.getInstance());
mTv.setText(ssb);

Android中SpannableString、SpannableStringBuilder与String的关系_第2张图片

1.3.3 将文字替换成图片 ImageSpan
String str = "img ImageSpan!";
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
ImageSpan imageSpan = new ImageSpan(this,R.mipmap.ic_launcher, ImageSpan.ALIGN_BOTTOM);
ssb.setSpan(imageSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTv.setText(ssb);

Android中SpannableString、SpannableStringBuilder与String的关系_第3张图片

1.3.4 文字可点击 ClickableSpan
String str = "点击事件 ImageSpan!";
SpannableStringBuilder ssb = new SpannableStringBuilder(str);
MClickableSpan mClickableSpan = new MClickableSpan(new MClickableSpan.OnClickListener() {
    @Override
    public void OnClick(View view) {
        Toast.makeText(MainActivity.this, "点击事件", Toast.LENGTH_SHORT).show();
    }
});
ssb.setSpan(mClickableSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 凡是有要执行的动作,都必须设置MovementMethod对象
mTv.setMovementMethod(LinkMovementMethod.getInstance());
mTv.setHighlightColor(ContextCompat.getColor(this, R.color.colorAccent));
mTv.setText(ssb);

static class MClickableSpan extends ClickableSpan {

    private OnClickListener onClickListener;

    interface OnClickListener {
        void OnClick(View view);
    }

    public MClickableSpan(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
        ds.setColor(0xFF5394f5);
        ds.setUnderlineText(false);
        ds.clearShadowLayer();
        ds.bgColor = Color.TRANSPARENT;
    }

    @Override
    public void onClick(@NonNull View widget) {
        onClickListener.OnClick(widget);
    }
}

Android中SpannableString、SpannableStringBuilder与String的关系_第4张图片

参考资料

SpannableString与SpannableStringBuilder
Android中span总结

TextView显示丰富多彩的文字(一)
TextView显示丰富多彩的文字(二)
TextView显示丰富多彩的文字(三)

你可能感兴趣的:(Android知识点总结)