TextView图文混排
大家都知道,textview有一个setcompounddrawables的方法来设置上下左右位置的图标,当然,也可以在xml布局文件中设置,然而问题来了,假如我们把图标放在左边,当我们让textview分多行显示的时候,会出现一种情况,左边的图标并不会与第一行对齐,而是与整个textview居中对齐。
即我们要的是下图:
结果是这个图:
怎么办呢?我们可以用图文混排:
我们可以利用spannablestring和imagespan。
1、构建spannablestring对象。
spannablestring spanstring = new spannablestring(textview.gettext().tostring());
2、获取drawable对象,即将我们的图案转换为drawable对象,并设置大小。
drawable tvdrawable = contextcompat.getdrawable(mcontext, r.drawable.pic); tvdrawable.setbounds(0, 0, tvdrawable.getminimumwidth(), tvdrawable.getminimumheight());
3、构建imagespan 对象
imagespan span = new imagespan(tvdrawable, imagespan.align_baseline);
4、设置给上面的spannablestring对象
spanstring.setspan(span, 0, 1, spannable.span_inclusive_exclusive);
5、最终设置给textview
textview.settext(spanstring)
加下来讲讲上面的方法:
1、imagespan对象,第二个参数为图像与文字的对齐方式,imagespan只带有两个对齐方式,分别是:align_baseline、align_bottom。
align_bottom 表示与文字内容的底部对齐,如果在构造imagespan时没有传入对齐方式,那么默认就是这种底部对齐。
align_baseline, 表示与文字内容的基线对齐
imagespan span = new imagespan(tvdrawable, imagespan.align_baseline);
2、setspan()方法
public void setspan(object what, int start, int end, int flags) { super.setspan(what, start, end, flags); }
what传入各种span类型的实例;
start和end标记要替代的文字内容的范围;
flags是用来标识在span范围内的文本前后输入新的字符时是否把它们也应用这个效果,它有如下几个:
spanned.span_exclusive_exclusive、
spanned.span_inclusive_exclusive、
spanned.span_exclusive_inclusive、
spanned.span_inclusive_inclusive
inclusive表示应用该效果,exclusive表示不应用该效果,如spanned.span_inclusive_exclusive表示对前面的文字应用该效果,而对后面的文字不应用该效果。
坑:
1、既然imagespan只带有两个对齐方式,那我们需要自己实现居中对齐:
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_baseline) { 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; } }
为何上面的自定义能够实现居中对齐呢?首先要了解paint.fontmetrics。
请看另一篇博客:https://www.cnblogs.com/tangzh/p/8692910.html
上一篇: 网站服务器是怎么样租用的?
下一篇: C++自学之路:3.1-简单变量