SpannableString实现TextView前添加图片

在做商城项目的时候,会遇到这种需求,在商品名称前面添加一个图片,来辨别商品是淘宝的还是天猫、京东、拼多多的。大概效果如下图所示。

这个效果可以用SpannableString来实现,具体代码如下所示。

 textView.setText(TextViewHelper.setLeftImage(context,
                "1",
                "3月25日,中国杯季军争夺战,国足对阵乌兹别克斯坦,比赛进行到第37分钟,国足0比1落后,韦世豪的一次背后铲人犯规十分威胁,直接造成乌兹别克斯坦的19号舒库罗夫被换下。对于这次犯规,央视解说员贺炜直言,这是红牌动作,奔着断腿去的。"));

其中帮助类代码如下:

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.Spanned;

public class TextViewHelper {

    /**
     * @param context 上下文
     * @param flag 商品类别
     * @param msg  商品名称
     * @return
     */
    public static SpannableString setLeftImage(Context context, String flag, String msg) {
        SpannableString spannableString = new SpannableString("  " + msg);
        Drawable rightDrawable = null;
        if ("".equals(flag)) {
            rightDrawable = context.getResources().getDrawable(R.mipmap.goods_taobao);
        } else if ("1".equals(flag)) {
            rightDrawable = context.getResources().getDrawable(R.mipmap.goods_tianmao);
        } else if ("2".equals(flag)) {
            rightDrawable = context.getResources().getDrawable(R.mipmap.goods_jingdong);
        } else if ("3".equals(flag)) {
            rightDrawable = context.getResources().getDrawable(R.mipmap.goods_pinduoduo);
        }
        rightDrawable.setBounds(0, 0, rightDrawable.getIntrinsicWidth(), rightDrawable.getIntrinsicHeight());

        spannableString.setSpan(new MyImageSpan(rightDrawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

}

在此之间,会遇到一个问题,图片不能居中显示。因为ImageSpan中只有ImageSpan.ALIGN_BASELINE和ImageSpan.ALIGN_BOTTOM两个选项,即使设置了这个参数,在不同手机上也可能出现不同的情况。即使同一段代码,也可能出现有的居上,有的居下的情况。解决方法就是自定义ImageSpan,并且重写getSize()和draw()方法,代码如下:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan;

public class MyImageSpan extends ImageSpan {

    public MyImageSpan( Context context,  Bitmap bitmap) {
        super(context, bitmap);
    }

    public MyImageSpan( Context context,  Bitmap bitmap, int verticalAlignment) {
        super(context, bitmap, verticalAlignment);
    }

    public MyImageSpan( Drawable drawable) {
        super(drawable);
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        try {
            Drawable d = getDrawable();
            Rect rect = d.getBounds();
            if (fm != null) {
                Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
                int fontHeight = fmPaint.bottom - fmPaint.top;
                int drHeight = rect.bottom - rect.top;

                int top = drHeight / 2 - fontHeight / 4;
                int bottom = drHeight / 2 + fontHeight / 4;

                fm.ascent = -bottom;
                fm.top = -bottom;
                fm.bottom = top;
                fm.descent = top;
            }
            return rect.right;
        } catch (Exception e) {
            return 20;
        }
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        try {
            Drawable d = getDrawable();
            canvas.save();
            int transY = 0;
            transY = ((bottom - top) - d.getBounds().bottom) / 2 + top;
            canvas.translate(x, transY);
            d.draw(canvas);
            canvas.restore();
        } catch (Exception e) {
        }
    }
    
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值