Android Span相关知识小记

1.SpannableString与SpannableStringBuilder简介

SpannableStringBuilder,SpannableString其实和String一样,都是一种字符串类型。不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示。比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉。SpannableString与SpannableStringBuilder区别就如String和StringBuilder一样。

2. setSpan()

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

object what :对应的各种Span,后面会提到;

int start:开始应用指定Span的位置,索引从0开始

int end:结束应用指定Span的位置,包不包含两头的数据,取决于flags的值

flag的取值

 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE --- 不包含start和end所在的端点              (a,b)
 Spanned.SPAN_EXCLUSIVE_INCLUSIVE --- 不包含端start,但包含end所在的端点       (a,b]
 Spanned.SPAN_INCLUSIVE_EXCLUSIVE --- 包含start,但不包含end所在的端点          [a,b)
 Spanned.SPAN_INCLUSIVE_INCLUSIVE--- 包含start和end所在的端点                  [a,b]

3. object what 各种设置

3.1字体颜色(ForegroundColorSpan)
在这里插入图片描述

/**
 * 设置字体颜色
 */
private void setColor() {
    String content = "SpannableStringBuilder 简介";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
    ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#FF4040"));
    stringBuilder.setSpan(foregroundColorSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.2背景颜色(BackgroundColorSpan)
这个是设置无圆角的背景,如果是要设置带圆角的背景,可查看本文最后的自定义类RoundBackgroundColorSpan。
在这里插入图片描述

/**
 * 设置背景颜色
 */
private void setBackgroundColor() {
    String content = "SpannableStringBuilder 简介";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
    //背景颜色
    BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.parseColor("#FF4040"));

    stringBuilder.setSpan(backgroundColorSpan, 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.3文本可点击,有点击事件(ClickableSpan)
在这里插入图片描述在这里插入图片描述

/**
 * 设置文本点击事件
 */
private void setClickableSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
    ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, "可点击", Toast.LENGTH_LONG).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            //去掉可点击文字的下划线
            ds.setUnderlineText(false);
        }
    };

    //文本可点击,有点击事件
    stringBuilder.setSpan(clickableSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    // 设置此方法后,点击事件才能生效
    contentTv.setMovementMethod(LinkMovementMethod.getInstance());
    此句用来消除点击后的背景异色
    contentTv.setHighlightColor(getResources().getColor(android.R.color.transparent));
    contentTv.setText(stringBuilder);
}

3.4 模糊效果(BlurMaskFilter)
在这里插入图片描述

/**
 * 设置模糊效果
 */
private void setBlurMaskFilterSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    MaskFilter filter = new BlurMaskFilter(4.0f, BlurMaskFilter.Blur.OUTER);
    MaskFilterSpan maskFilterSpan = new MaskFilterSpan(filter);

    stringBuilder.setSpan(maskFilterSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.5 删除线效果 (StrikethroughSpan)
在这里插入图片描述

/**
 * 设置删除线效果 (StrikethroughSpan)
 */
private void setStrikethroughSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    stringBuilder.setSpan(new StrikethroughSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

    contentTv.setMovementMethod(LinkMovementMethod.getInstance());
    contentTv.setText(stringBuilder);
}

3.6 下划线效果(UnderlineSpan)
在这里插入图片描述

/**
 * 设置下划线效果(UnderlineSpan)
 */
private void setUnderlineSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    stringBuilder.setSpan(new UnderlineSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.7 字体绝对大小效果(AbsoluteSizeSpan)
在这里插入图片描述

/**
 * 设置字体绝对大小效果(AbsoluteSizeSpan)
 */
private void setAbsoluteSizeSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    AbsoluteSizeSpan ab=new AbsoluteSizeSpan(30,true);
    //文本字体绝对的大小

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.8 设置图片(DynamicDrawableSpan)基于底部
在这里插入图片描述

/**
 * 设置图片(DynamicDrawableSpan)基于底部
 */
private void setDynamicDrawableSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    DynamicDrawableSpan dynamicDrawableSpan = new DynamicDrawableSpan() {
        @Override
        public Drawable getDrawable() {
            Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
            drawable.setBounds(0, 0, 50, 50);
            return drawable;
        }
    };

    stringBuilder.setSpan(dynamicDrawableSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.9 设置图片(ImageSpan )
在这里插入图片描述

/**
 * 设置设置图片(ImageSpan )
 */
private void setImageSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher_round);
    drawable.setBounds(0, 0, 100, 100);
    ImageSpan ab = new ImageSpan(drawable);
   
    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.10 相对字体大小(RelativeSizeSpan )
在这里插入图片描述

/**
 * 设置相对字体大小(RelativeSizeSpan )
 */
private void setRelativeSizeSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    stringBuilder.setSpan(new RelativeSizeSpan(3.0f), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.10 基于X的缩放(ScaleXSpan )
在这里插入图片描述

/**
 * 设置 基于X的缩放(ScaleXSpan )
 */
private void setScaleXSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    stringBuilder.setSpan(new ScaleXSpan(3.0f), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.11 字体样式:粗体、斜体等(StyleSpan )
在这里插入图片描述

/**
 * 设置字体样式:粗体、斜体等(StyleSpan )
 */
private void setStyleSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    StyleSpan ab = new StyleSpan(Typeface.BOLD_ITALIC);

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.12 上标(SubscriptSpan )
在这里插入图片描述

/**
 * 设置上标(SuperscriptSpan  )
 */
private void setSuperscriptSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    SuperscriptSpan ab = new SuperscriptSpan();

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.14 下标(SubscriptSpan )
在这里插入图片描述

/**
 * 设置下标(SubscriptSpan )
 */
private void setSubscriptSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    stringBuilder.setSpan(new SubscriptSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.12 字体、大小、样式和颜色(TextAppearanceSpan)
在这里插入图片描述

/**
 * 设置字体、大小、样式和颜色(TextAppearanceSpan)
 */
private void setTextAppearanceSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    //自定义文本样式
    TextAppearanceSpan ab = new TextAppearanceSpan(this, android.R.style.TextAppearance_Medium);

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.13 文本字体(TypefaceSpan )
在这里插入图片描述

/**
 * 设置文本字体(TypefaceSpan )
 */
private void setTypefaceSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    //文字字体
    TypefaceSpan ab = new TypefaceSpan("serif");

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}

3.14 文本超链接(URLSpan )
在这里插入图片描述

/**
 * 设置文本超链接(URLSpan )
 */
private void setURLSpan() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);

    URLSpan ab = new URLSpan("http://www.baidu.com");

    stringBuilder.setSpan(ab, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setMovementMethod(new LinkMovementMethod());
    contentTv.setText(stringBuilder);
}

3.15 使用带圆角的按钮背景
在这里插入图片描述

/**
 * 设置带有圆角的背景
 */
private void setRoundBackgroundColor() {
    String content = "CSDN-专业IT技术社区";
    SpannableStringBuilder stringBuilder = new SpannableStringBuilder(content);
    //背景颜色
    RoundBackgroundColorSpan roundBackgroundColorSpan = new RoundBackgroundColorSpan(
            getResources().getColor(R.color.color_yellow),
            getResources().getColor(R.color.color_white),
            getResources().getDimensionPixelSize(R.dimen.textsize_28px),
            getResources().getDimensionPixelSize(R.dimen.view_distance_6));

    stringBuilder.setSpan(roundBackgroundColorSpan, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTv.setText(stringBuilder);
}
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.style.ReplacementSpan;

/**
 * author : wyy
 * time   : 2019/1/22
 * desc   : 自定义 span 的圆角背景图片,具体尺寸可能要看情况,不一定通用
 */
public class RoundBackgroundColorSpan extends ReplacementSpan {
    private int bgColor;
    private int textColor;
    private int textSize;
    private int mRadius;
    private int mSize;

    public RoundBackgroundColorSpan(int bgColor, int textColor, int textSize, int radius) {
        super();
        this.bgColor = bgColor;
        this.textColor = textColor;
        this.textSize = textSize;
        this.mRadius = radius;
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        mSize = (int) (paint.measureText(text, start, end) + 2 * mRadius);
        //mSize就是span的宽度,span有多宽,开发者可以在这里随便定义规则
        //我的规则:这里text传入的是SpannableString,start,end对应setSpan方法相关参数
        //可以根据传入起始截至位置获得截取文字的宽度,最后加上左右两个圆角的半径得到span宽度
        return mSize;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        int color1 = paint.getColor();//保存文字颜色
        paint.setColor(this.bgColor);//设置背景颜色
        paint.setAntiAlias(true);    // 设置画笔的锯齿效果

        RectF oval = new RectF(x, y + paint.ascent(), x + mSize , y + paint.descent());
        //设置文字背景矩形,x为span其实左上角相对整个TextView的x值,y为span左上角相对整个View的y值。paint.ascent()获得文字上边缘,paint.descent()获得文字下边缘
        canvas.drawRoundRect(oval, mRadius, mRadius, paint);//绘制圆角矩形,第二个参数是x半径,第三个参数是y半径

        paint.setTextSize(this.textSize);
        paint.setColor(textColor);
        canvas.drawText(text, start, end, x + mRadius, y , paint);//绘制文字
    }
}

几点需要注意的

  1. 字体的点击后效果,要设置背景色透明,否则会有点击后效果,影响界面

参考链接:
https://blog.csdn.net/baidu_31956557/article/details/78339071
https://www.cnblogs.com/galibujianbusana/p/6490461.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值