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();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章