SpannableString 与 类似shape边框的背景效果

参考:
Android自定义圆角Span背景
使用canvas.drawRoundRect()时,解决四个圆角的线比较粗的问题

效果图:

这里写图片描述

布局:

 <TextView
        android:id="@+id/tv"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:text=""
        android:textColor="#000000"
        android:textSize="25sp" />

代码:

TextView mTv = (TextView) this.findViewById(R.id.tv);

String str1 = "商家自配";
String str2 = "佳洁士3D炫白亮白抛光牙刷120g 1x36";
String str = str1 + str2;

SpannableString spannableString = new SpannableString(str);
int bgColor = Color.parseColor("#ff8041");
int textColor = Color.parseColor("#ff8041");
RoundBackgroundColorSpan span = new RoundBackgroundColorSpan(bgColor, textColor, 15);
spannableString.setSpan(span, 0, str1.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mTv.setText(spannableString);
mTv.setMovementMethod(LinkMovementMethod.getInstance());

核心代码:

/**
 * span包含三部分:shape、文字和距离其他文字的空白
 */

public class RoundBackgroundColorSpan extends ReplacementSpan {
    private int mRadius;
    private int bgColor;
    private int textColor;
    private int mSize;

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

    /**
     * @param start 第一个字符的下标
     * @param end   最后一个字符的下标
     * @return span的宽度
     */
    @Override
    public int getSize(@NonNull Paint paint,  
                                CharSequence text,  
                                int start,  
                                int end,  
                                Paint.FontMetricsInt fm) {
        mSize = (int) (paint.measureText(text, start, end) + 2 * mRadius);
        return mSize + 5;//5:距离其他文字的空白
    }

    /**
     * @param y baseline
     */
    @Override
    public void draw(@NonNull Canvas canvas, 
                                CharSequence text, 
                                int start,  
                                int end,  
                                float x,  
                                int top, 
                                int y, int bottom,  
                                @NonNull Paint paint) {
        int defaultColor = paint.getColor();//保存文字颜色
        float defaultStrokeWidth = paint.getStrokeWidth();

        //绘制圆角矩形
        paint.setColor(bgColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setAntiAlias(true);
        RectF rectF = new RectF(x + 2.5f, y + 2.5f + paint.ascent(), x + mSize, y + paint.descent());
        //设置文字背景矩形,x为span其实左上角相对整个TextView的x值,y为span左上角相对整个View的y值。
        // paint.ascent()获得文字上边缘,paint.descent()获得文字下边缘
        //x+2.5f解决线条粗细不一致问题
        canvas.drawRoundRect(rectF, mRadius, mRadius, paint);

        //绘制文字
        paint.setColor(textColor);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(defaultStrokeWidth);
        canvas.drawText(text, start, end, x + mRadius, y, paint);//此处mRadius为文字右移距离

        paint.setColor(defaultColor);//恢复画笔的文字颜色
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值