平日开发过程中,我们难免会遇到一些图文混排的格式,文字,自然是利用TextView控件去实现,若是单行文字,相信无论是左边还是右边添加图片对小伙伴们来说都不是难事,而且可以利用drawableleft或者直接利用ImageView实现就可以了。
不过,若是要求文字显示多行时,无论是利用drawableleft,还是ImageView,想要做到换行不错位,都是不可能的,此时,我们就要利用富文本显示效果的SpannableString了。
SpannableString其实和String一样,都是一种字符串类型,SpannableString可以直接作为TextView的显示文本,不同的是SpannableString可以通过使用其方法setSpan方法实现字符串各种形式风格的显示,重要的是可以指定设置的区间,也就是为字符串指定下标区间内的子字符串设置格式。
至于SpannableString的各种用法,这里就不多做介绍了,感兴趣的小伙伴可以查看这篇文章
https://www.cnblogs.com/qynprime/p/8026672.html
下面是针对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)