Android TextView 富文本 SpannableString 与 SpannableStringBuilder

Android TextView 富文本 SpannableString 与 SpannableStringBuilder


单个TextView 要实现复杂的富文本效果,可借助SpannableString实现。
主要实现方法 SpannableString.setSpan(Object what, int start, int end, int flags)

what 参数,控制文本效果,主要有以下类型

  • BackgroundColorSpan 背景色
  • ClickableSpan 点击事件
  • ForegroundColorSpan 文本颜色(前景色)
  • MaskFilterSpan 修饰效果,如模糊(BlurMaskFilter)浮雕(EmbossMaskFilter)
  • MetricAffectingSpan 父类,一般不用
  • RasterizerSpan 光栅效果
  • StrikethroughSpan 删除线
  • SuggestionSpan 占位符
  • UnderlineSpan 下划线
  • AbsoluteSizeSpan 文本字体,绝对大小
  • DynamicDrawableSpan 设置图片,基于文本基线或底部对齐
  • ImageSpan 图片
  • RelativeSizeSpan 文本字体,相对大小
  • ReplacementSpan 父类,一般不用
  • ScaleXSpan 基于x轴缩放
  • StyleSpan 字体样式:粗体、斜体等
  • SubscriptSpan 下标(数学公式会用到)
  • SuperscriptSpan 上标(数学公式会用到)
  • TextAppearanceSpan 文本外貌(包括字体、大小、样式和颜色)
  • TypefaceSpan 文本字体
  • URLSpan 文本超链接

start、end 参数

start 指定span开始位置。包括该位置。
end 指定span结束位置,不包括该位置。

flags 参数,指定前后文本会不会用span样式

  • Spannable.SPAN_INCLUSIVE_EXCLUSIVE 前面用,后面不用
  • Spannable.SPAN_INCLUSIVE_INCLUSIVE 前后都会使用span样式
  • Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 前后都不会使用span样式
  • Spannable.SPAN_EXCLUSIVE_INCLUSIVE 前面不用,后面用


基本使用效果

  • 背景色
    这里写图片描述
// 背景色
private void setBackgroundColor() {
    SpannableString spannableString = new SpannableString("测试用的文本修改字体背景颜色");
    //BackgroundColorSpan backSpan = new BackgroundColorSpan(Color.parseColor("#0000ff"));
    BackgroundColorSpan backSpan = new BackgroundColorSpan(Color.RED);
    //BackgroundColorSpan backSpan = new BackgroundColorSpan(CommonUtils.getColor(TestActivity.this, R.color.colorAccent));
    spannableString.setSpan(backSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 前景色
    这里写图片描述
// 前景色
private void setForegroundColor() {
    SpannableString spannableString = new SpannableString("测试用的文本修改字体前景颜色");
    //ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#ff0000"));
    //ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.BLUE);
    ForegroundColorSpan colorSpan = new ForegroundColorSpan(CommonUtils.getColor(TestActivity.this, R.color.colorAccent));
    spannableString.setSpan(colorSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv02.setText(spannableString);
}

  • 模糊
    这里写图片描述
// 修饰效果-模糊
private void setBlurMaskFilter() {
    // 注意:使用 MaskFilterSpan 修饰效果,需要关闭硬件加速,不然没有效果出来。
    // 在AndroidManifest.xml中对应的activity设置android:hardwareAccelerated="false"
    // 参看:https://stackoverflow.com/questions/46089196/how-to-using-android-spannablestring-and-maskfilterspan-to-blur-some-text-from-t

    SpannableString spannableString = new SpannableString("测试用的文本修饰效果之模糊测试");
    MaskFilterSpan blurSpan0 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
    MaskFilterSpan blurSpan4 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.SOLID));
    MaskFilterSpan blurSpan8 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.OUTER));
    MaskFilterSpan blurSpan12 = new MaskFilterSpan(new BlurMaskFilter(20, BlurMaskFilter.Blur.INNER));
    spannableString.setSpan(blurSpan0, 0, 2, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    spannableString.setSpan(blurSpan4, 4, 6, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    spannableString.setSpan(blurSpan8, 8, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    spannableString.setSpan(blurSpan12, 12, 14, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 删除线
    这里写图片描述
// 删除线
private void setStrikethroughSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本加上删除线");
    StrikethroughSpan backSpan = new StrikethroughSpan();
    spannableString.setSpan(backSpan, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 下划线
    这里写图片描述
// 下划线
private void setUnderlineSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本加上下划线");
    UnderlineSpan span = new UnderlineSpan();
    spannableString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 字体大小(绝对大小)
    这里写图片描述
// 字体大小(相对大小)
private void setRelativeSizeSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本图片字体大小(相对大小)");
    RelativeSizeSpan span = new RelativeSizeSpan(1.5f);
    spannableString.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 基于x轴缩放
    这里写图片描述
// 基于x轴缩放
private void setScaleXSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本基于x轴缩放");
    ScaleXSpan span = new ScaleXSpan(0.5f);
    spannableString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);

    SpannableString spannableString2 = new SpannableString("测试用的文本基于x轴缩放");
    for (int i = 0; i < spannableString2.length(); i++) {
        float proportion = (float) (0.5f + (0.1 * i));
        spannableString2.setSpan(new ScaleXSpan(proportion), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    tv02.setText(spannableString2);
}

  • 加粗斜体
    这里写图片描述
// 加粗斜体
private void setStyleSpan() {
    SpannableString spannableString = new SpannableString("测试加粗测试斜体测试加粗斜体");
    // 加粗
    StyleSpan span = new StyleSpan(Typeface.BOLD);
    spannableString.setSpan(span, 2, 4, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

    // 斜体
    StyleSpan span2 = new StyleSpan(Typeface.ITALIC);
    spannableString.setSpan(span2, 6, 8, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

    // 加粗斜体
    StyleSpan span3 = new StyleSpan(Typeface.BOLD_ITALIC);
    spannableString.setSpan(span3, 10, 14, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);

    tv01.setText(spannableString);
}

  • 上标下标(数学公式会用到)
    这里写图片描述
// 上标下标(数学公式会用到)
private void setSubscriptSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本2018");
    SuperscriptSpan span = new SuperscriptSpan();
    spannableString.setSpan(span, 6, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);

    SpannableString spannableString2 = new SpannableString("测试用的文本2018");
    SubscriptSpan span2 = new SubscriptSpan();
    spannableString2.setSpan(span2, 6, 10, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv02.setText(spannableString2);
}

  • 文本外貌(包括字体、大小、样式和颜色)
// 文本外貌(包括字体、大小、样式和颜色)
private void setTextAppearanceSpan() {
    SpannableString sstr = new SpannableString("测试文本修改字体修改大小修改样式修改颜色");
    ColorStateList csl = getResources().getColorStateList(R.color.red);

    TextAppearanceSpan span = new TextAppearanceSpan("default", android.graphics.Typeface.BOLD, 20, csl, null);
    sstr.setSpan(span, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    tv01.setText(sstr);
}

  • 设置字体
// 设置字体
private void setTypefaceSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本");
    // "monospace", "serif", and "sans-serif".
    TypefaceSpan span = new TypefaceSpan("serif");
    spannableString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
}

  • 设置链接
    这里写图片描述
// 设置链接
private void setURLSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本这是链接地址");
    spannableString.setSpan(new URLSpan("https://baidu.com"), 0, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
    // 执行动作需要设置MovementMethod
    tv01.setMovementMethod(LinkMovementMethod.getInstance());
}

  • 点击事件
    这里写图片描述
// 设置点击事件
private void setClickableSpan() {
    SpannableString spannableString = new SpannableString("测试用的文本点击事件");
    ClickableSpan span = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            showToast("点一点");
        }
    };
    spannableString.setSpan(span, spannableString.length() - 4, spannableString.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    tv01.setText(spannableString);
    // 执行动作需要设置MovementMethod
    tv01.setMovementMethod(LinkMovementMethod.getInstance());
}


参看:
https://blog.csdn.net/fengyuzhengfan/article/details/38459299
https://www.jianshu.com/p/f004300c6920

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值