自定义了一个MyView控件,重写它的onDraw来绘制一个点,和一串文字。绘制圆的坐标为200,300,绘制文字的坐标也为200,300。
最初以为文字也是以中心为基准的,然后绘制之后发现文字并不是垂直居中的,它的中心与圆心并不在一条水平线上。文字会偏上。
绘制结果如下图
这里就要说到FontMetrics,绘制文本时,使用FontMetrics对象,计算位置的坐标。通过Paint对象的getFontMetrics()方法可以获得到FontMetrics对象,查看这个类的定义
/**
* 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的属性值,绘制出标注线来如下。
从绘制的结果可以清晰的看出,五条线之与文字的位置。实际文字的绘制是以baseLine的位置为基准的。
那么要想让文字也以中心为基准,需要让整体下移一些。
现在画了一个点坐标(X,Y),要使文字也在Y垂直居中,可以根据上图算出,descent是之于base的正数值,ascent是之于base的负数,可根据上边公式求出相差的距离Z,最后文字要垂直居就让文字的纵坐标为Y+Z。这样文字与点就是居中对齐了。
下边贴出绘制几条标注线的代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.rgb(0, 0, 0));
textPaint.setTextSize(300);
textPaint.setColor(Color.WHITE);
// FontMetrics对象
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
String text = "ajg,'hHAé你好";
// 计算每一个坐标
float baseX = 0;
float baseY = 400;
float topY = baseY + fontMetrics.top;
float ascentY = baseY + fontMetrics.ascent;
float descentY = baseY + fontMetrics.descent;
float bottomY = baseY + fontMetrics.bottom;
float leadingY = baseY + fontMetrics.leading;
// 绘制文本
canvas.drawText(text, baseX, baseY, textPaint);
// BaseLine描画
Paint baseLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
baseLinePaint.setTextSize(40);
baseLinePaint.setColor(Color.RED);
canvas.drawLine(0, baseY, getWidth(), baseY, baseLinePaint);
canvas.drawText("baseLine", 0, baseY, baseLinePaint);
// TopLine描画
Paint topLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
topLinePaint.setColor(Color.RED);
topLinePaint.setTextSize(40);
canvas.drawLine(0, topY, getWidth(), topY, topLinePaint);
canvas.drawText("top", 0, topY, baseLinePaint);
// AscentLine描画
Paint ascentLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
ascentLinePaint.setColor(Color.RED);
ascentLinePaint.setTextSize(40);
canvas.drawLine(0, ascentY, getWidth(), ascentY, ascentLinePaint);
canvas.drawText("ascent", 0, ascentY, ascentLinePaint);
// DescentLine描画
Paint descentLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
descentLinePaint.setColor(Color.RED);
descentLinePaint.setTextSize(40);
canvas.drawLine(0, descentY, getWidth(), descentY, descentLinePaint);
canvas.drawText("descent", 0, descentY, descentLinePaint);
// BottomLine描画
Paint bottomLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bottomLinePaint.setColor(Color.BLACK);
bottomLinePaint.setTextSize(40);
canvas.drawLine(0, bottomY, getWidth(), bottomY, bottomLinePaint);
canvas.drawText("bottom", 240, bottomY, bottomLinePaint);
// LeadingLine描画
Paint leadingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
leadingPaint.setColor(Color.MAGENTA);
leadingPaint.setTextSize(40);
canvas.drawLine(0, leadingY, getWidth(), leadingY, leadingPaint);
canvas.drawText("leading", 240, leadingY, leadingPaint);
// Paint paint=new Paint();
// paint.setColor(Color.parseColor("#be8fff"));
// paint.setTextSize(100);
// canvas.drawCircle(200, 300, 10, paint);
// canvas.drawText("云涛", 200, 300, paint);
}
本文介绍了在Android自定义View中如何使用FontMetrics进行文字垂直居中对齐。通过分析FontMetrics的属性,如top、ascent、descent等,计算出文字相对于基线的位置,并调整坐标实现居中效果。示例代码展示了如何绘制标注线以理解这些属性的作用。

1073

被折叠的 条评论
为什么被折叠?



