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