图文混排 ——SpannableStringBuilder的使用

简介

SpannableStringBuilder与String一样都实现了CharSequence类,用来存储字符串,区别在于SpannableStringBuilder有一个setSpan()函数,能给给存储的字符串添加各种各样的格式或者属性,,将原来的String以不同的样式显示出来,比如加上下划线、背景颜色、字体颜色、设置点击监听、设置超链接等。

  • setSpan()函数:

    SpannableStringBuilder ssb = new SpannableStringBuilder("图文混排");
    
    /**
     * what : 行为
     * start :开始指定Span的位置
     * end : 结束指定Span的位置
     *       eg:1,3即截取出“文混”
     * flags : 标识当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式
     */
    ssb.setSpan(Object what,int start,int end,int flags);
    
  • what:

    ForegroundColorSpan(int color)//字体颜色
    BackgroundColorSpan(int color)//字体的背景颜色
    UnderlineSpan()//下划线
    StrikethroughSpan()//删除线
    URLSpan(String url)
    StyleSpan(int style)//字体样式
    AbsoluteSizeSpan(int size)//字体大小,以px为单位
    AbsoluteSizeSpan(int size,boolean dip)//字体大小,true则以dp为单位
    RelativeSizeSpan(float proportion)//字体的相对大小
    ImageSpan(Context context, int resourceId)//插入图片
    
  • flags:

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

示例

1.为文本加上超链接

private  SpannableStringBuilder ssb;
ssb = new SpannableStringBuilder("超级链接:网络 ");
    ssb.setSpan(new URLSpan("https://www.baidu.com"), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 截取出“网络”
    ssb.setSpan(new ForegroundColorSpan(Color.LTGRAY),5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//设置前景色(字体颜色)为灰色
    textview.setMovementMethod(LinkMovementMethod.getInstance());// 让链接的点击事件响应的必要一句代码

2.文字后面添加图片

    TextView text = new TextView(this);
    StringBuilder sb = new StringBuilder("我是HTML:");
    sb.append("<img src=\"" + R.drawable.icon_pic + "\">");

    CustomImageGetter imageGetter = new CustomImageGetter(this, CustomImageGetter.DEFAULT,CustomImageGetter.DEFAULT);

    text.setText(Html.fromHtml(sb.toString(),imageGetter, null)); 

3.为指定的区间设置指定的颜色

    ssb = new SpannableStringBuilder("为指定的区间[1,4)设置指定的颜色");
    ssb.setSpan(new ForegroundColorSpan(Color.GREEN), 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);// 基本使用_1:为指定的区间设置指定的颜色

4.追加字符并设置指定颜色

    ssb = new SpannableStringBuilder("追加字符");
    ssb.append("fuck!");// 基本使用_2:追加字符
    ssb.setSpan(new ForegroundColorSpan(Color.RED), 4, 8, Spannable.SPAN_MARK_POINT);

5.设置字体的背景颜色

    ssb = new SpannableStringBuilder("设置字体背景色 ");
    ssb.setSpan(new BackgroundColorSpan(Color.GRAY), new String("设置字体").length(), new String("设置字体背景色 ").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 设置背景色为青色

    ssb = new SpannableStringBuilder("设置字体背景色 Long值方式");
    ssb.setSpan(new BackgroundColorSpan(Color.parseColor("#ff0000")), new String("设置字体").length(), new String("设置字体背景色 ").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 设置背景色为青色

6.设置下划线

    ssb = new SpannableStringBuilder("设置下划线");
    // 设置下划线
    ssb.setSpan(new UnderlineSpan(), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

7.设置删除线

    ssb = new SpannableStringBuilder("设置删除线");
    ssb.setSpan(new StrikethroughSpan(), 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

ps:请读忽略鼠标位置,用真机测试的~

8.点击调起拨号界面

    ssb = new SpannableStringBuilder("超级链接:电话 ");
    ssb.setSpan(new URLSpan("tel:13912345678"), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 电话

图文混排 ——SpannableStringBuilder的使用_第1张图片

9.点击发送邮件

    ssb = new SpannableStringBuilder("超级链接:邮件 ");
    ssb.setSpan(new URLSpan("mailto:[email protected]"), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 邮件
    ssb.setSpan(new ForegroundColorSpan(Color.YELLOW), 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

图文混排 ——SpannableStringBuilder的使用_第2张图片

10.点击调起发送短信的界面

    ssb = new SpannableStringBuilder("超级链接:短信 ");
    ssb.setSpan(new URLSpan("sms:13912345678"), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 短信
    ssb.setSpan(new ForegroundColorSpan(Color.BLUE), 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

图文混排 ——SpannableStringBuilder的使用_第3张图片

11.点击调起地图,并定位到指定位置

    ssb = new SpannableStringBuilder("超级链接:地图 ");
    ssb.setSpan(new URLSpan("geo:38.899533,-77.036476"), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //
    ssb.setSpan(new ForegroundColorSpan(Color.GREEN), 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

图文混排 ——SpannableStringBuilder的使用_第4张图片

12.超链接文本,设置点击监听

    // 注意:设置链接后,指定区间的文本会变成蓝色,会遮住以前设置的颜色,所以应在设置链接后再为指定区间的文字设置颜色
    ssb = new SpannableStringBuilder("设置链接:文本 ");
    ssb.setSpan(new URLSpan("cacaca") {
        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, "点击了设置的链接", 0).show();
        }
    }, 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new ForegroundColorSpan(Color.RED), 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

图文混排 ——SpannableStringBuilder的使用_第5张图片

13.设置字体样式

    ssb = new SpannableStringBuilder("设置字体样式正常,粗体,斜体,粗斜体 ");
    // 设置字体样式正常,粗体,斜体,粗斜体
    ssb.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), 6, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 正常
    ssb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 9, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 粗体
    ssb.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 斜体
    ssb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), 15, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 粗斜体

14.设置字体大小

    ssb = new SpannableStringBuilder("设置字体大小(绝对值:单位:像素/单位:像素)");
    ssb.setSpan(new AbsoluteSizeSpan(20), new String("设置字体大小(绝对值,").length(), new String("设置字体大小(绝对值,单位:像素,").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new AbsoluteSizeSpan(20, true), new String("设置字体大小(绝对值,单位:像素,").length(), new String("设置字体大小(绝对值,单位:像素,单位:像素)").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 第二个参数boolean
    // dip,如果为true,表示前面的字体大小单位为dip,否则为像素,上同

    ssb = new SpannableStringBuilder("设置字体大小(相对值:一半/两倍,单位:像素) 参数表示为默认字体大小的多少倍 ");
    ssb.setSpan(new RelativeSizeSpan(0.5f), new String("设置字体大小(相对值:").length(), new String("设置字体大小(相对值:一半/").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 0.5f表示默认字体大小的一半
    ssb.setSpan(new RelativeSizeSpan(2.0f), new String("设置字体大小(相对值:一半/").length(), new String("设置字体大小(相对值:一半/两倍,").length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 2.0f表示默认字体大小的两倍


15.添加图片

    //文字后面添加图片
    ssb = new SpannableStringBuilder("我的后面添加图片:  ");
    ssb.setSpan(new ImageSpan(this, R.drawable.ic_launcher), 9, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    //文字中间添加图片
    ssb = new SpannableStringBuilder("我的中 间添加图片  ");
    ssb.setSpan(new ImageSpan(this, R.drawable.ic_launcher), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

16.图片的点击事件

    ssb = new SpannableStringBuilder("图片点击事件的处理  ");
    ssb.setSpan(new ImageSpan(this, R.drawable.ic_launcher), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, "图片点击事件的处理 ", 0).show();
        }
    }, 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

17.设置某段文字的点击监听

    ssb = new SpannableStringBuilder("更复杂的点击效果");
    ssb.setSpan(new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, "更复杂的点击效果", 0).show();
        }
    }, 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    ssb = new SpannableStringBuilder("更复杂的点击效果");
    ssb.setSpan(new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, "更复杂的点击效果", 0).show();
        }

        //不改变设置监听的文字的颜色
        public void updateDrawState(TextPaint ds) {
            ds.setUnderlineText(false);
        }
    }, 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

参考文章:SpannableString与SpannableStringBuilder使用【原创】

你可能感兴趣的:(图文混排详解)