SpannableString和SpannableStringBuilder的使用总结

安卓开发中TextView 是我们最常用的控件之一,我们用TextView为我们在页面中展示文本。展示普通文本当然没有任何难度,使用TextView的setText()方法设置一个字符串就可以了,但是当我们需要在文本中展示不同格式文本的时候,设置普通的字符串就不行了。那该怎么办?当然就说到我们今天的主角了。SpannableString和SpannableStringBuilder

首先来说SpannableString

SpannableString和String一样都是一种字符串类型,他们都实现了CharSequence,所以SpannableString也可以直接使用TextView的setText()方法设置文本。SpannableString的特别之处就在于SpannableString可以打造丰富多彩的文本显示效果。SpannableString可以通过使用其方法setSpan()实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。

可以轻松实现以下效果:

  1. 自定义文本中文字的字体大小(包括绝对大小和相对大小,区别看下面解释)
  2. 设置文本中文字的前景色、背景色
  3. 为文本中的文字设置下划线,删除线
  4. 设置文本中的内容上标、下标
  5. 为文字设置风格,粗体斜体等
  6. 设置图文混排,即文字中添加图片
  7. 可以为部分文本设置点击事件

以上是一些常用的效果,并不是全部。

下面说一下怎么实现这些效果。

SpannableString有一个方法叫做setSpan(),我们就是用这个方法来实现不同展示效果的。
这个方法如下所示:

public void setSpan(Object what, int start, int end, int flags) {
    super.setSpan(what, start, end, flags);
}

setSpan()方法有四个参数,其中what就是所要设置的格式,start是需要设置格式的子字符串的起始下标,end就是结束下标,但并不包括这个位置。flag一共有四种值可选。如下:

  1. Spannable. SPAN_INCLUSIVE_EXCLUSIVE 前面包括,后面不包括,意思就是在这段文本前部插入新的文本会应用该样式,而在文本后部插入新文本则不会应用该样式
  2. Spannable. SPAN_INCLUSIVE_INCLUSIVE 前面包括,后面包括,意思就是在这段文本前部插入新的文本会应用该样式,在文本后部插入新文本也会应用该样式
  3. Spanned.SPAN_EXCLUSIVE_EXCLUSIVE 前面不包括,后面不包括
  4. Spanned.SPAN_EXCLUSIVE_INCLUSIVE 前面不包括,后面包括

这里先看一个SpannableString的简单实现:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        ForegroundColorSpan foregroundColorSpan=new ForegroundColorSpan(Color.parseColor("#FF0000"));
        ss.setSpan(foregroundColorSpan,2,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

上述代码实现的效果是:
这里写图片描述
SpannableString的setSpan()方法可以同时使用多个,实现多种效果叠加。

setSpan()方法中的what是最重要的一个参数,对应各种span,不同的span对应不同的样式。接下来我们就来看一下不同的几种常见的span以及效果。

为文本设置背景色 BackgroundColorSpan
代码如下:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        BackgroundColorSpan backgroundColorSpan=new BackgroundColorSpan(Color.parseColor("#FFFF00"));
        ss.setSpan(backgroundColorSpan,2,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果如图:
这里写图片描述
为文本设置下划线以及删除线

UnderlineSpan:下划线
StrikethroughSpan :删除线
代码示例:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        UnderlineSpan underlineSpan=new UnderlineSpan();//下划线span
        StrikethroughSpan strikethroughSpan=new StrikethroughSpan();//删除线
        ss.setSpan(underlineSpan,3,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(strikethroughSpan,0,3,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果展示:
这里写图片描述

设置文本字体 AbsoluteSizeSpan (设置的是绝对大小,直接用具体数值指定文字大小)
代码:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        AbsoluteSizeSpan absoluteSizeSpan=new AbsoluteSizeSpan(30,true);
        ss.setSpan(absoluteSizeSpan,3,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果如图:
这里写图片描述

设置文本字体 RelativeSizeSpan(设置的是相对大小,在TextView原有的文字大小的基础上,相对设置文字大小)
代码如下:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        RelativeSizeSpan relativeSizeSpan=new RelativeSizeSpan(0.5f);
        ss.setSpan(relativeSizeSpan,3,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果:
这里写图片描述
设置字体样式(粗体、斜体等) StyleSpan
代码:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        StyleSpan styleSpan=new StyleSpan(Typeface.BOLD);
        ss.setSpan(styleSpan,3,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果:
这里写图片描述
设置文本中的内容上标 SuperscriptSpan 、下标SubscriptSpan
代码:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        SuperscriptSpan superscriptSpan=new SuperscriptSpan();//上标
        SubscriptSpan subscriptSpan=new SubscriptSpan();//下标
      //ss.setSpan(superscriptSpan,3,5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(subscriptSpan,0,2,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

这里写图片描述
文本中插入图片 ImageSpan
代码:

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        ImageSpan imageSpan=new ImageSpan(this,R.mipmap.ic_launcher);
        ss.setSpan(imageSpan,2,3,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);

效果:
这里写图片描述
给部分文本设置点击事件 ClickableSpan

        TextView main_tv=findViewById(R.id.main_tv);
        SpannableString ss=new SpannableString("其实我是一个好人");
        ClickableSpan clickableSpan=new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(SecondActivity.this, "点击了", Toast.LENGTH_SHORT).show();
            }
        };
        ss.setSpan(clickableSpan,2,4,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        main_tv.setText(ss);
        main_tv.setMovementMethod(LinkMovementMethod.getInstance());

使用ClickableSpan设置点击事件,最后还需要加上main_tv.setMovementMethod(LinkMovementMethod.getInstance())这一句,不然不生效。
效果:
这里写图片描述

以上就是一些常用的span

接着说SpannableStringBuilder

SpannableStringBuilder 与 SpannableString 的区别就和string 与 stringBuilder 的区别类似。就是SpannableStringBuilder可以使用append()方法拼接,而SpannableString不可拼接。其他没有多大区别。

以上简单总结了一下SpannableStringBuilder和SpannableString的用法,只是一些常用的用法,还有很多东西有待学习。

你可能感兴趣的:(SpannableString和SpannableStringBuilder的使用总结)