SpannableStringBuilder实现图文混排
1.我的后面添加图片
ssb = new SpannableStringBuilder("我的后面添加图片: "); ssb.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 9, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
2.我的中间添加图片
ssb = new SpannableStringBuilder("我的中 间添加图片 "); ssb.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
3.图片点击事件的处理
ssb = new SpannableStringBuilder("图片点击事件的处理 "); ssb.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); ssb.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(MainActivity.this, "图片点击事件的处理 ", Toast.LENGTH_SHORT).show(); } }, 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
4.背景带圆角,可设置颜色,角度
1 if (position % 2 == 0) { 2 strShow = "300英雄" + homeDataBean.User + ":" + homeDataBean.Content; 3 spannable = new SpannableStringBuilder(strShow); 4 spannable.setSpan(new RadiusBackgroundSpan(Color.parseColor("#fdc14f"), 10), 5 0, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 6 } else { 7 strShow = "枪界" + homeDataBean.User + ":" + homeDataBean.Content; 8 spannable = new SpannableStringBuilder(strShow); 9 spannable.setSpan(new RadiusBackgroundSpan(Color.parseColor("#9885fc"), 10), 10 0, 2, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 11 }
1 /** 2 * 背景带圆角,可设置颜色,角度 3 * Created by g on 2018/1/23. 4 */ 5 public class RadiusBackgroundSpan extends ReplacementSpan { 6 7 private int mSize; 8 private int mColor; 9 private int mRadius; 10 11 /** 12 * @param color 背景颜色 13 * @param radius 圆角半径 14 */ 15 public RadiusBackgroundSpan(int color, int radius) { 16 mColor = color; 17 mRadius = radius; 18 } 19 20 @Override 21 public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { 22 mSize = (int) (paint.measureText(text, start, end) + 2 * mRadius); 23 //mSize就是span的宽度,span有多宽,开发者可以在这里随便定义规则 24 //我的规则:这里text传入的是SpannableString,start,end对应setSpan方法相关参数 25 //可以根据传入起始截至位置获得截取文字的宽度,最后加上左右两个圆角的半径得到span宽度 26 return mSize; 27 } 28 29 @Override 30 public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { 31 int color = paint.getColor();//保存文字颜色 32 paint.setColor(mColor);//设置背景颜色 33 paint.setAntiAlias(true);// 设置画笔的锯齿效果 34 RectF oval = new RectF(x, y + paint.ascent(), x + mSize, y + paint.descent()); 35 //设置文字背景矩形,x为span其实左上角相对整个TextView的x值,y为span左上角相对整个View的y值。paint.ascent()获得文字上边缘,paint.descent()获得文字下边缘 36 canvas.drawRoundRect(oval, mRadius, mRadius, paint);//绘制圆角矩形,第二个参数是x半径,第三个参数是y半径 37 paint.setColor(color);//恢复画笔的文字颜色 38 canvas.drawText(text, start, end, x + mRadius, y, paint);//绘制文字 39 } 40 }
6.设置图标:
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(); } }