/**
* 绘制
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(text, 0 ,getHeight()/2 ,mPaint);
}
当我们用如上方法绘制文字时,会常常发现文字并不是位于自定义view高度的中间,这是因为我们忽略了文字本身的高度。
在X轴居中
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//拿到字符串的宽度
float stringWidth = mPaint.measureText(text);
float x =(getWidth()-stringWidth)/2;
canvas.drawText(text, x ,getHeight()/2 ,mPaint);
}
利用measureText(String text)
这个方法,很容易拿到要绘制文字的宽度,再根据(getWidth()-stringWidth)/2
简单计算,就可以得到在X
轴起始绘制坐标
在Y轴居中
想要在Y
轴居中,就要确定出绘制文字baseline
时的所在Y
轴的坐标。在Android
中,和文字高度相关的信息都存在FontMetrics
对象中。。
FontMetrics
是Paint
的一个静态内部类,源码如下:
/**
* Class that describes the various metrics for a font at a given text size.
* Remember, Y values increase going down, so those values will be positive,
* and values that measure distances going up will be negative. This class
* is returned by getFontMetrics().
*/
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;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
在FontMetrics
有五个float
类型值:
-
leading
留给文字音标符号的距离 -
ascent
从baseline
线到最高的字母顶点到距离,负值 -
top
从baseline
线到字母最高点的距离加上ascent
-
descent
从baseline
线到字母最低点到距离 -
bottom
和top
类似,系统为一些极少数符号留下的空间。top
和bottom
总会比ascent
和descent
大一点的就是这些少到忽略的特殊符号
baseline
上为负,下为正。可以理解为文字坐标系中的x
轴,baseline可以理解为文字的坐标系。文字的绘制是从baseline
开始的
那么如何确定文字的Y轴坐标?
由于文字绘制是从baseline
开始,所以想要文字的正中心和DrawTextView
的中心重合,baseline
就不能和getHeight()/2
重合,而且baseline
要在getHeight()/2
下方。
但要在下方多少?就是2号线和3号线之间的距离。
|ascent|
=descent
+ 2 * ( 2号线和3号线之间的距离 )
换一种方式思考:2号线和3号线之间的距离 = (|ascent| + desent) / 2 - desent,这样是不是更好理解
修改代码如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//文字的x轴坐标
float stringWidth = mPaint.measureText(text);
float x = (getWidth() - stringWidth) / 2;
//文字的y轴坐标
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float y = getHeight() / 2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2;
canvas.drawText(text, x, y, mPaint);
}