10月 132020
 
关于SpannableStringBuilder使用的文章,分享下
1.简介

SpannableStringBuilder和SpannableString也可以用来存储字符串,它们俩都有SetSpan()方法,可以对字符串设置背景色,字体大小颜色,下划线,删除线,粗体斜体等。
SpannableStringBuilder和SpannableString的区别:
SpannableString在构造对象的时候必须一次传入,之后无法再更换String,
SpannableStringBuilder可以使用append方法不断的拼接多个String。
因为Spannable等最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。

2.setSpan()

 /*给特定范围的字符串设定Span样式
 * Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作
 * what 对应的各种Span 
 * start Span指定的开始位置,索引从0开始
 * end  Span指定的结束的位置,不包括尾,()包含头不包含尾
 * flags   用来指定范围前后输入新的字符时,会不会应用效果的
  ----Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式 
  ----Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
  ----Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。
  ----Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。
 */

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

演示

 EditText et = (EditText) findViewById(R.id.edittext);
        SpannableStringBuilder stringBuilder =new SpannableStringBuilder("我来测试flags属性");
        ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
        stringBuilder.setSpan(span,1,3, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        et.setText(stringBuilder);

这里用的是 flag : Spanned.SPAN_INCLUSIVE_EXCLUSIVE,在前面插入新字符会改变字体颜色,但范围后面插入的新字符字体颜色不变。

spanablestring_01.png

插入新字符后效果

spanstring_02.png
改变字体大小

AbsoluteSizeSpan span = new AbsoluteSizeSpan(16);

spanstring_text_size.png
改变字体背景颜色

BackgroundColorSpan span = new BackgroundColorSpan(Color.BLUE);

spanstring_text_background.png
改变字体为粗体斜体

StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);//粗体斜体

spanstring_bold.png
删除线

StrikethroughSpan span = new StrikethroughSpan();//删除线

spanstring_strikethrough.png
下划线

UnderlineSpan span = new UnderlineSpan();//下划线

spanstring_underline.png
文字换为图片

Drawable d = getResources().getDrawable(R.mipmap.ic_launcher);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);

spanstring_text_to_img.png

示例 (区间价格的显示)
生成效果

spannablestringbuilder_price.png

TextView tvPrice =(TextView)findViewById(R.id.tv_price);
tvPrice.setText(formatPriceString(this,"100.00","230.87","件"));

public static SpannableStringBuilder formatPriceString(Context context, String minPrice, String maxPrice, String unit) {
        try {
            while (minPrice.contains(".") && (minPrice.endsWith("0") || minPrice.endsWith("."))) {
                minPrice = minPrice.subSequence(0, minPrice.length() - 1).toString();
            }
            while (maxPrice.contains(".") && (maxPrice.endsWith("0") || maxPrice.endsWith("."))) {
                maxPrice = maxPrice.subSequence(0, maxPrice.length() - 1).toString();
            }

            Float minPriceFloat = Float.valueOf(minPrice);//100.0
            Float maxPriceFloat = Float.valueOf(maxPrice);//230.87
            DecimalFormat decimalFormat = new DecimalFormat("#0.00");
            boolean isBig = false;
            if (minPriceFloat > tenThousand || maxPriceFloat > tenThousand) {
                isBig = true;
                minPriceFloat = minPriceFloat / 10000;
                maxPriceFloat = maxPriceFloat / 10000;
                minPrice = decimalFormat.format(minPriceFloat);
                maxPrice = decimalFormat.format(maxPriceFloat);
            }
            SpannableStringBuilder builder = new SpannableStringBuilder("价格:¥");
            int dp12 = getPixByDp(12, context);
            int length = builder.length();
            builder.setSpan(new AbsoluteSizeSpan(dp12), 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//字体大小
            builder.setSpan(new ForegroundColorSpan(Color.parseColor("#919191")), 0, length - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);//字体颜色
            builder.setSpan(new ForegroundColorSpan(Color.parseColor("#eb413d")), length - 1, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);

            SpannableString priceSpan = new SpannableString(minPrice + "~" + maxPrice);
            int dp16 = getPixByDp(16, context);
            int lengthPrice = priceSpan.length();
            priceSpan.setSpan(new AbsoluteSizeSpan(dp16), 0, lengthPrice, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            priceSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#eb413d")), 0, lengthPrice, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
            builder.append(priceSpan);
            SpannableString unitSpan;
            if (!isBig) {
                unitSpan = new SpannableString("元/" + unit);
            } else {
                unitSpan = new SpannableString("万元/" + unit);
            }
            int lengthUnit = unitSpan.length();
            unitSpan.setSpan(new AbsoluteSizeSpan(dp12), 0, lengthUnit, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            unitSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#919191")), 0, lengthUnit, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
            builder.append(unitSpan);
            return builder;
        } catch (Exception e) {

        }
        return new SpannableStringBuilder("");
    }

链接:https://www.jianshu.com/p/a157cd9297b5

Sorry, the comment form is closed at this time.