我们在自定义TextView时的onDraw()方法是这样写的:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
int dy = 0;
dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;
int baseLine = getHeight()/2 + dy;
canvas.drawText(mText,0,baseLine,mPaint);
}
首先我们来看一下这个方法:drawText(String text, float x, float y, Paint paint)
那么问题来了,我们该如何计算y的值呢?
下面我们来看一张图:
ascent = ascent线的y坐标 - baseline线的y坐标;//负数
descent = descent线的y坐标 - baseline线的y坐标;//正数
top = top线的y坐标 - baseline线的y坐标;//负数
bottom = bottom线的y坐标 - baseline线的y坐标;//正数
leading = top线的y坐标 - ascent线的y坐标;//负数
上面是FontMetrics的各个属性和纵坐标点的数值关系。
我们假设top的y坐标为y0,ascent的y坐标为y1,baseLine的y坐标为y2,descent的y坐标为y3,bottom的y坐标为y4。
getHeight()/2 = y4 - y0;
Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
y4 = y2 + fontMetricsInt.bottom;
y0 = y2 + fontMetricsInt.top;
getHeight()/2 = (fontMetricsInt.bottom - fontMetricsInt.top)/2;
dy = getHeight()/2 - (y4 - y2);
又y4 - y2 = fontMetricsInt.bottom;
所以dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom。
搞清楚基线的计算问题,drawText这个方法的核心难点就解决了。