在Textview左边或右边添加图标 ,换行不错位

3,990 阅读3分钟

在Textview左边或右边添加图标 ,换行不错位

平日开发过程中,我们难免会遇到一些图文混排的格式,文字,自然是利用TextView控件去实现,若是单行文字,相信无论是左边还是右边添加图片对小伙伴们来说都不是难事,而且可以利用drawableleft或者直接利用ImageView实现就可以了。

不过,若是要求文字显示多行时,无论是利用drawableleft,还是ImageView,想要做到换行不错位,都是不可能的,此时,我们就要利用富文本显示效果的SpannableString了。

SpannableString其实和String一样,都是一种字符串类型,SpannableString可以直接作为TextView的显示文本,不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。

至于SpannableString的各种用法,这里就不多做介绍了,感兴趣的小伙伴可以查看这篇文章

www.cnblogs.com/qynprime/p/…

下面是针对textview左右添加图标换行不错位的代码实现

SpannableString spannableString = new SpannableString(" " + item.getGod_des());
Drawable drawable = mContext.getResources().getDrawable(R.mipmap.loading);
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
spannableString.setSpan(new VerticalImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mtv.setText(spannableString);

关于上面代码

1.创建出SpannableString后,参数的item.getGod_des()为你的textview要显示的内容,为什么要在前面加上一个空格呢?

因为这个空格就是你的图标要占的位置,所以多加一个空格为图标腾出一个位置,否则图标会默认占用第一个字来显示,如果图标与文字之间想留间隙,还可以多加一个空格。

2.把你的图标转成一个drawable,并且给drawable设置最小宽高。

3.VerticalImageSpan: 这个是一个可以垂直居中的ImageSpan,实现代码会放在下边

4.解释一下0,1: 开始位置从0开始,到第一个位置结束。 如果大家想在最后面加上图标,可以把0换成字符串长度-1,把1换成字符串长度,切记要在后面加一个空格占位,否则会切割掉你原本的字符串哦。

5.设置textview,这个就不多说了

VerticalImageSpan的代码

public class VerticalImageSpan extends ImageSpan {

public VerticalImageSpan(Drawable drawable) {
    super(drawable);

}

public VerticalImageSpan(Bitmap b) {
    super(b);
}

@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
                 @NonNull Paint paint) {

    Drawable b = getDrawable();
    Paint.FontMetricsInt fm = paint.getFontMetricsInt();
    int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
    canvas.save();
    canvas.translate(x, transY);//绘制图片位移一段距离
    b.draw(canvas);
    canvas.restore();
}
}

基本的代码就是上面这两段,不过,针对这种经常用得到的代码,我们其实可以封装成一个工具类,平时用到时,只需要传入文字和图标,就可以实现想要的效果。

工具类代码
public class TextAndPictureUtil {

    private TextAndPictureUtil mTextAndPictureUtil;
    
    private TextAndPictureUtil(){}
    
    public  TextAndPictureUtil getInstance(){
        if (mTextAndPictureUtil==null){
            synchronized (TextAndPictureUtil.class){
                if (mTextAndPictureUtil==null){
                    mTextAndPictureUtil=new TextAndPictureUtil();
                }
            }
        }
        
        return mTextAndPictureUtil;
    }
    
    public static SpannableString getText(Context mcontext,String text, int drawId){
        SpannableString spannableString = new SpannableString("  " + text);
        Drawable drawable = mcontext.getResources().getDrawable(drawId);
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        spannableString.setSpan(new VerticalImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }
}

调用

TextAndPictureUtil.getInstance().getText("IT烟酒僧",R.drawable.it)