1.问题
今天接到一个需求,UI设计图实现方式如下
刚开始一看,这简单,imgView和TextView结合一下不就完事了,emmm......不对,又想了一下没有这么简单,如果只是两者的结合,会导致布局变成这个鸟样
我嘞个叉,这显然没有达到UI的效果图,要不和美工商量一下修改需求。。。。。这显然不符合用户体验,我决定试一试实现这个,经过分析,这中布局方式图片需要动态的添加上去,使用简单的控件组合是解决不了问题的,首先想到的是使用HTMl的那种格式,但是那种灵活性不是很好,后来想到了imageSpan,获取图片的资源文件,然后通过自定义imageSpan重新绘制图片添加到textView前面。
一顿操作猛如虎,添加的过程中遇到了一个问题,绘制的图片插入到textView中会导致第一个字显示不全,研究分析,图片在插入过程中需要一个索引位置,我在做插入过程中索引位置0-1,所以会导致文本在加载的时候第一个字会被覆盖掉,哈哈,这能难倒我,废话不多说,直接上代码。
2.解决代码
/**
* 处理图文混排
*
* @param tvRemark:textView
* @param remark:文本信息
*/
private void getTextView(TextView tvProductRemark, String remark) {
SpannableStringBuilder builder = new SpannableStringBuilder(remark);
String substring = remark.substring(0, 1);
Drawable drawable = ContextCompat.getDrawable(mActivity,
R.mipmap.图片资源);
drawable.setBounds(0, 0, drawable.getMinimumWidth() / 2,
drawable.getMinimumHeight() / 2);
MyImageSpan span = new MyImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
builder.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.insert(1, substring);
tvProductRemark.setText(builder);
}
自定义的MyImageSpan如下:
public class MyImageSpan extends ImageSpan {
public static final int ALIGN_CENTER = 2;
public MyImageSpan(Drawable d, int verticalAlignment) {
super(d, verticalAlignment);
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
Drawable b = getDrawable();
canvas.save();
Paint.FontMetricsInt fm = paint.getFontMetricsInt();
//系统默认为ALIGN_BOTTOM
int transY = bottom - b.getBounds().bottom;
if (mVerticalAlignment == ALIGN_CENTER) {
transY -= fm.descent;
} else {
transY = ((y + fm.descent + y + fm.ascent) / 2
- b.getBounds().bottom / 2);
}
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
Drawable b = getDrawable();
Rect rect = b.getBounds();
if (fm != null) {
Paint.FontMetricsInt painFm = paint.getFontMetricsInt();
int fontHeight = (painFm.bottom - painFm.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;
}
}
不要问我怎么解决第一个字被覆盖的,看代码,然后我继续说,我是把文本的第一个字给截取下来了,然后插入到图片和文本中间,完美解决。谁还有比较恰当解决办法欢迎提出来。希望这篇文章对工作在一线的广大码农少走弯路,有所帮助。