在实际开发中,有一些精细的UI需求可能会比整体逻辑要花费更多时间。但是产品整体视觉效果的提升,也往往就在这些微小的差异中。例如listView中的复杂item,在item的标题或者边角处可能会需要加各种标签或icon。实现它们有多种方式,比如imageView、iconfont矢量图、span,其中span可以方便的进行图文混排,并设置文字的样式,下面我就来介绍一种自定义imageSpan的实现。
public class FixedSizeImageSpan extends ImageSpan {
private int textColor;
private int width;
private int height;
public FixedSizeImageSpan(Context context, int resourceId, int textColor,
int width, int height, boolean isDip) {
super(context, resourceId);
if (isDip) {
width = DimenHelper.dip2px(context, width);
height = DimenHelper.dip2px(context, height);
}
this.textColor = textColor;
this.width = width;
this.height = height;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fm) {
return width;
}
private static final float OVERSHOOT_RATIO = 0.125f;
private static final float bgOffsetY = -1;
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end,
float x, int top, int y, int bottom, Paint paint) {
Drawable drawable = getDrawable();
canvas.save();
drawable.setBounds(0, 0, width, height);
canvas.translate(Math.round(x),
Math.round(y - drawable.getBounds().bottom + height * OVERSHOOT_RATIO) + bgOffsetY);
drawable.draw(canvas);
canvas.restore();
canvas.save();
paint.setColor(textColor);
float textWidth = paint.measureText(text, start, end);
canvas.translate((width - textWidth) / 2, -(height - paint.getTextSize()) / 2);
canvas.drawText(text, start, end, x, y, paint);
canvas.restore();
}
}
TextView textView = (TextView) findViewById(R.id.text_view);
FixedSizeImageSpan span = new FixedSizeImageSpan(this, R.mipmap.ic_launcher, Color.BLACK, 60, 60, true);
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
stringBuilder.append("hello world")
.setSpan(span, 0, 5, SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(stringBuilder);
调用时,只要把text和spand都塞到SpannableStringBuilder中就行了,SpannableStringBuilder实现了CharSequence,可以直接传给textView。