Canvas.drawText()方法
关于文档中的canvas.drawText(String, float, float, Paint)方法:
/**
* Draw the text, with origin at (x,y), using the specified paint. The
* origin is interpreted based on the Align setting in the paint.
*
* @param text The text to be drawn
* @param x The x-coordinate of the origin of the text being drawn
* @param y The y-coordinate of the baseline of the text being drawn
* @param paint The paint used for the text (e.g. color, size, style)
*/
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
paint.getNativeInstance(), paint.mNativeTypeface);
}
参数x:绘制文本起源的x坐标
参数y:绘制文本基线的y坐标
那么什么是文本基线的y坐标?使用如下代码来测试文本基线的y坐标:
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
canvas.translate(mX, mY);
canvas.drawText(mText, mX, mY, mTextPaint);
canvas.drawLine(mX, mY, mX + bounds.width(), mY, mLinePaint);
其中mX=8,mY=12,canvas.translate(mX, mY)将坐标原点移至到(mX,mY)。
以下为绘制后的图:
从图中可以看出,文本基线的y坐标并非文本高度的中点,文本基线就只是一条简单的文本所处的直线。
关于测量文本的高度
1.getTextBounds(String, int, int, Rect)方法
如果想要居中固定的文本,可以用该方法获得文本高度。
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
canvas.translate(mX, mY);
canvas.drawText(mText, mX, mY, mTextPaint);
canvas.drawRect(new RectF(mX, mY + bounds.top, mX + bounds.width(), mY + bounds.bottom), mLinePaint);
这里有两张绘制的示例图:
从图中可以看出,不同的文本内容,得到的文本高度不同。如果只是将文本居中绘制,那结果没有问题;如果将文本绘制在其它地方,那么可能会出现差错。
2.Paint.FontMetrics
使用 mTextPaint.getFontMetrics()方法得到的Paint.FontMetrics对象,可以用来获得文本高度,且不论文本内容如何变化,文本高度都是一样,保持不变(从上面的两张图可以看出来)。
Paint.FontMetrics有五个参数:
- top:在给定字体大小的文本中,最高文字的基线到顶部的距离。
- ascent:距离文本基线以上的推荐距离。
- descent:距离文本基线以下的推荐距离。
- bottom:在给定字体大小的文本中,最低文字的基线到底部的距离。
- leading:添加在文本行之间额外的推荐距离。
top,ascent,descent,bottom,leading的具体位置如下:
其中,top:绿色;ascent:蓝色;基线:黄色;descent:紫色;bottom:红色。这里descent和bottom重合了。
所以文本的高度为:
float height = fontMetrics.bottom - fontMetrics.top + fontMetrics.leading;
因此,例如绘制相关的文本:
Rect bounds = new Rect();
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
canvas.drawText(mText, mX, mY + (fontMetrics.bottom - fontMetrics.top) / 2, mTextPaint);
canvas.drawText(mText, mWidth / 2 - bounds.centerX(), mHeight / 2 - bounds.centerY(), mTextPaint);
总结:绘制居中的文本使用getTextBounds()方法获得高度,否则使用 Paint.FontMetrics获得高度。