android SpannableStringBuilder TextView 背景带颜色,圆角

if (position % 2 == 0) {
    strShow = "300英雄" + homeDataBean.User + ":" + homeDataBean.Content;
    spannable = new SpannableStringBuilder(strShow);
    spannable.setSpan(new RadiusBackgroundSpan(Color.parseColor("#fdc14f"), 10),
            0, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
} else {
    strShow = "枪界" + homeDataBean.User + ":" + homeDataBean.Content;
    spannable = new SpannableStringBuilder(strShow);
    spannable.setSpan(new RadiusBackgroundSpan(Color.parseColor("#9885fc"), 10),
            0, 2, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
/**
 * 背景带圆角,可设置颜色,角度
 * Created by g on 2018/1/23.
 */
public class RadiusBackgroundSpan extends ReplacementSpan {

    private int mSize;
    private int mColor;
    private int mRadius;

    /**
     * @param color  背景颜色
     * @param radius 圆角半径
     */
    public RadiusBackgroundSpan(int color, int radius) {
        mColor = color;
        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 color = paint.getColor();//保存文字颜色
        paint.setColor(mColor);//设置背景颜色
        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.setColor(color);//恢复画笔的文字颜色
        canvas.drawText(text, start, end, x + mRadius, y, paint);//绘制文字
    }
}

一般常用的是Spannable.SPAN_EXCLUSIVE_EXCLUSIVE,对于Spannable.SPAN_INCLUSIVE_EXCLUSIVE一直似懂非懂。

顾名思义:

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //前后都不包括

Spannable.SPAN_INCLUSIVE_EXCLUSIVE  //前包括后不包括

Spannable.SPAN_EXCLUSIVE_INCLUSIVE  //前不包括后包括

Spannable.SPAN_INCLUSIVE_INCLUSIVE  //前后都包括

设置图标:

if (!TextUtils.isEmpty(tagHorn)) {
 int sixe = ScreenUtils.sp2px(mContext, 15);
    EmojiconSpan imageSpan = new EmojiconSpan(mContext, R.mipmap.laba_icon,
            (int) (sixe), DynamicDrawableSpan.ALIGN_BASELINE, (int) (sixe));
    spannable.setSpan(imageSpan, strShow.indexOf(tagHorn), strShow.indexOf(tagHorn) + tagHorn.length(),
            Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}

public class EmojiconSpan extends DynamicDrawableSpan {
    private final Context mContext;

    private final int mResourceId;

    private final int mSize;

    private final int mTextSize;

    private int mHeight;

    private int mWidth;

    private int mTop;

    private Drawable mDrawable;

    private WeakReference<Drawable> mDrawableRef;

    int nment = 5;

    public EmojiconSpan(Context context, int resourceId, int size, int alignment, int textSize) {
        super(alignment);
        mContext = context;
        mResourceId = resourceId;
        mWidth = mHeight = mSize = size;
        mTextSize = textSize;
    }

    public Drawable getDrawable() {
        if (mDrawable == null) {
            try {
                mDrawable = mContext.getResources().getDrawable(mResourceId);
                mHeight = mSize;
                mWidth = mHeight * mDrawable.getIntrinsicWidth() / mDrawable.getIntrinsicHeight();
                mTop = (mTextSize - mHeight) / 2;
                mDrawable.setBounds(0, mTop - nment, mWidth, mTop + mHeight);
            } catch (Exception e) {
                LogUtils.d(e.toString());
            }
        }
        return mDrawable;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        //super.draw(canvas, text, start, end, x, top, y, bottom, paint);
        Drawable b = getCachedDrawable();
        canvas.save();

        int transY = bottom - b.getBounds().bottom;
        if (mVerticalAlignment == ALIGN_BASELINE) {
            transY = top + ((bottom - top) / 2) - ((b.getBounds().bottom - b.getBounds().top) / 2) - mTop;
        }

        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }

    private Drawable getCachedDrawable() {
        if (mDrawableRef == null || mDrawableRef.get() == null) {
            mDrawableRef = new WeakReference<Drawable>(getDrawable());
        }
        return mDrawableRef.get();
    }
}

猜你喜欢

转载自blog.csdn.net/beyondforme/article/details/79138054