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
点击文字可以打开一个URLURLSpan
文字可点击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);

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);

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);

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);
    }
}

参考资料

SpannableString与SpannableStringBuilder
Android中span总结

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值