使用Canvas的draw***方法去绘制一些图像图形,绘制的坐标是从Canvas左上角开始计算的,但是drawText就不一样,如果你传递进去字符串,会发现文字的位置和你指定的不一样。
传入的其实位置为(0,0),结果文字没显示出来。
```
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
super.drawText(text, x, y, paint);
}
```
这里的x,y其实为下图的BaseLine的坐标即五角心的位置,当我们传入(0,0)时,就会出现上面的情况。
除了基线以外,如上图所示,另外还有四条线,分别是ascent,descent,top,bottom。
```
ascent = ascent线的y坐标 - baseline线的y坐标;
descent = descent线的y坐标 - baseline线的y坐标;
top = top线的y坐标 - baseline线的y坐标;
bottom = bottom线的y坐标 - baseline线的y坐标;
```
那ascent,descent,top,bottom这些线的位置要怎么计算出来呢?
Android给我们提供了一个类:FontMetrics,它里面有四个成员变量:
```
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;
}
```
获取所绘文字宽度所占的高度
```
int height = (int) (bottom - top);
```
获取所绘文字宽度所占的宽度
```
int width = (int) mPaint.measureText(text);
```
最小矩形获取
```
/**
* 获取最小矩形
*/
mPaint.getTextBounds(text,0,text.length(),minRect);
/**
* 这两个宽高与上面的宽高不一样,这个是包裹文字的最小矩形的宽高,比上面的两个数值小
*/
int minwWidth = minRect.width();
int minHeight = minRect.height();
```
红色区域就是最小的最小矩形,绿色的就是所绘文字的矩形。
计算baseline
1、给定顶点的坐标
```
int drawTextTop = 600;
/**
* 因为top = baseLineY + fontMetrics.top,
* 所以baseLineY = top - fontMetrics.top;
*/
int baseLineY1 = (int) (drawTextTop - fontMetrics.top);
```
2、给定中心点的位置
```
/**
* 给定中心线
*/
int center = 1000;
Paint.FontMetrics fontMetrics2 = mPaint.getFontMetrics();
int baseLine = (int) (center + (fontMetrics2.bottom - fontMetrics2.top)/2 - fontMetrics2.bottom);
```
fontMetrics2.bottom - fontMetrics2.top表示所绘文字的矩形的高
(fontMetrics2.bottom - fontMetrics2.top)/2则为高的一半
(fontMetrics2.bottom - fontMetrics2.top)/2 - fontMetrics2.bottom)则为中心线到baseline的距离,所以baseline的距离就是center加上这段距离。
千万要记住,这里计算的是距离,不是坐标,不是坐标,不然就难以理解。
绘制多行文字
```
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float top = fontMetrics.top;
float bottom = fontMetrics.bottom;
//mPaint.setTextAlign(Paint.Align.CENTER);
/**
* 则每一行文字的高度为
*/
//float height = bottom - top;
float baseLine = height/3 + (bottom - top)/2 - bottom;
for (int i = 0; i < strs.length;i++){
float offset = i * (bottom - top);
canvas.drawText(strs[i],width/3,baseLine + offset,mPaint);
}
}
```
具体代码:https://github.com/fengyuehan/Test/tree/master/customview/src/main/java/com/example/customview/drawText