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