Android自定义Span示例

在实际开发中,有一些精细的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();
    }
}


它的效果是可以为一段文字添加指定大小的背景图片,当然也可以没有文字只有图片,只要把文字设为“ ”即可。它继承于ImageSpan,主要通过重载draw来实现。在draw函数中,对背景和文字的位置进行了计算,先后把背景和文字画了出来。


        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。


具体代码见:https://github.com/wlkdb/example_span

猜你喜欢

转载自blog.csdn.net/wlkdb/article/details/74364652
今日推荐