其实在drawText方法中,中传入的第三个参数y的实际意义是文字的基线所在的位置!
public void drawText(String text, float x, float y, Paint paint)
上面这个构造函数是最常用的drawText方法,传进去一个String对象就能画出对应的文字。这里x、y两个参数需要非常注意,(x,y)是并不是绘制文字所在矩形的左上角的点。比如,要画"harvic's blog"这几个字,这个(x,y)坐标应当是下图中绿色小点的位置。注意:这个x是基于paint.setTextAlign(Paint.Align.LEFT);来的。
再强调一遍:y所代表的是基线的位置!
把ascent、descent 值打印出来,发现 ascent 为 - 316,descent 为 82 ,因此可以计算出基线(偏移)为117。
这里的 ascent 和 descent 的值,实际是基于基线而得。可理解为:以文字基线为准,向上平移316像素为绘制区域的顶,向下平移82像素为绘制区域的底(基线向上为负 向下为正)。
已知基线与绘制区顶相距316,与底相距82,可以得出绘制区高度为 descent - ascent:82 - (-316) = 398。
绘制区中线高度为( descent - ascent)/ 2 = 398 / 2 = 199 。
绘制区中线高度等价于中线与绘制区底之间的距离,这个距离减去 基线与绘制区底 之间的距离,就是
中线与基线之间的距离: (descent - ascent) / 2 - descent = 199 - 82 = 117。
推导完毕上代码:
/**
* 计算绘制文字时的基线到中轴线的距离
*
* @param p
* @return 基线和centerY的距离
*/
public static float getBaseline(Paint p) {
FontMetrics fontMetrics = p.getFontMetrics();
return (fontMetrics.descent - fontMetrics.ascent) / 2 -fontMetrics.descent;
// 一样
//return (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
}
@Override
protected void onDraw(Canvas canvas) {
//坐标(0,0)在左上角,此时基线的y坐标就是高度的一半(中轴线) +基线到中轴线的距离
canvas.drawText(mText, 0, getHeight() / 2 + getBaseline(mPaint), mPaint);
}