在开发中常常会遇到标签(图片)+文字的需求,实现方式一般采用SpannableString的方式来实现。 这时候会遇到图片ImageSpan没有办法居中的问题。在解决这个问题之前,先学习字体属性Paint.FontMetrics。
图片1 图片2通过上面的示意图,再看下FontMetrics
类:
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;//最高字符到baseline的值,即ascent的最大值
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;//系统建议的,绘制单个字符时,baseline至字符最高处的距离
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;//系统建议的,绘制单个字符时,baseline至字符最低处的距离
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;//最低字符到baseline的值
/**
* The recommended additional space to add between lines of text.
*/
public float leading;//上一行字符的descent到下一行字符ascent之间的距离,行间距
}
ascent线Y坐标 = baseline线的y坐标 + fontMetric.ascent;
descent线Y坐标 = baseline线的y坐标 + fontMetric.descent;
top线Y坐标 = baseline线的y坐标 + fontMetric.top;
bottom线Y坐标 = baseline线的y坐标 + fontMetric.bottom;
ImageSpan
在ImageSpan的构造函数中有一个对齐方式的参数,但只提供了 ALIGN_BASELINE(顶部对齐)、ALIGN_BOTTOM (底部对齐)两种对齐方式,没有居中对齐的方式, 所以只能重写ImageSpan实现图片的居中。
public void draw(Canvas canvas, CharSequence text,int start, int end, float x, int top, int y, int bottom, Paint paint)
参数解析:
- x:要绘制的image的左边框到textview左边框的距离。
- y:替换文字的基线坐标。
- top:替换改行文字的最顶部位置。
- bottom:替换改行文字的最底部位置,行间距属于上一行,因而bottom是行间距的底部位置。
然后重写draw()
方法即可实现图片居中,实现方式如下:
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
Drawable drawable = getDrawable();
Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
int transY = (y + fontMetricsInt.descent + y + fontMetricsInt.ascent) / 2 - drawable.getBounds().bottom/2;
canvas.save();
canvas.translate(x,transY);
drawable.draw(canvas);
canvas.restore();
}
- y +fontMetricsInt.descent得到字体的descent线坐标
- y + fontMetricsInt.ascent得到字体的ascent线坐标
- 两者相加除以2,得到改行文字的中线坐标
- drawable.getBounds().bottom/2得到图片中线坐标
- 然后两者相减,即可获得图片需要移动多长的距离可以居中
- 最后将相减得到的距离传给
canvas.translate(x,transY)
即可
网友评论