文字位置信息¶
准备基础类BaseView,继承View类。
public class BaseView extends View {
static final int LINE_OFFSET = 60;
protected Paint notePaint = new Paint();
protected Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
protected Rect textRect = new Rect();
public BaseView(Context context) {
this(context, null);
}
public BaseView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BaseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
绘制文字的方法canvas.drawText
,需要指定字符串,绘制起始坐标,画笔paint。
起始坐标的y值所在横线在后面也称为 baseline 。
获取文字边界¶
从图中可以看到文字的部分笔画是可以超出边线的。比如开头的j
和结尾的r
字符。
使用Paint.getTextBounds
方法获取文字的边界。
绘制上图的部分代码
private void drawBounds(Canvas canvas, float tx, float ty, String onShowText) {
canvas.drawText(onShowText, tx, ty, textPaint); // 写字
textPaint.getTextBounds(onShowText, 0, onShowText.length(), textRect); // 获取text边界
notePaint.setStrokeWidth(3);
notePaint.setColor(Color.parseColor("#EF6C00"));
// 左边线
canvas.drawLine(tx, ty - textRect.height() - LINE_OFFSET, tx, ty + LINE_OFFSET, notePaint);
// 右边线
canvas.drawLine(tx + textRect.width(), ty - textRect.height() - LINE_OFFSET, tx + textRect.width(), ty + LINE_OFFSET, notePaint);
notePaint.setColor(Color.parseColor("#FF0277BD"));
// 上边线
canvas.drawLine(tx - LINE_OFFSET, ty - textRect.height(), tx + textRect.width() + LINE_OFFSET, ty - textRect.height(), notePaint);
notePaint.setColor(Color.parseColor("#00695C"));
// y - baseline
canvas.drawLine(tx - LINE_OFFSET, ty, tx + textRect.width() + LINE_OFFSET, ty, notePaint);
}
获取text尺寸信息¶
需要使用Paint.FontMetrics
类。它有5个属性
属性 | 介绍 |
---|---|
top | 从baseline到最高的文字顶部的最大距离 |
ascent | 单行距(singled spaced)时,baseline上方空间的推荐距离 |
descent | 单行距时,baseline下方空间的推荐距离 |
bottom | baseline到最下方字符的最大距离 |
leading | 多行文字之间推荐使用的额外空间 |
使用Paint.getFontMetrics()
方法获取Paint.FontMetrics
。
注意,top
和ascent
是负值。
绘制上图的方法
private void drawFontMetrics(Canvas canvas, float x, float y, String text) {
canvas.drawText(text, x, y, textPaint);
textPaint.getTextBounds(text, 0, text.length(), textRect);
Paint.FontMetrics fm = textPaint.getFontMetrics();
notePaint.setStrokeWidth(1);
notePaint.setColor(Color.BLACK);
canvas.drawText(String.format(Locale.CHINA, "top:%.2f, bottom:%.2f", fm.top, fm.bottom), x, y + notePaint.getTextSize() * 2.5f, notePaint);
canvas.drawText(String.format(Locale.CHINA, "ascent:%.2f, descent:%.2f, leading:%.2f", fm.ascent, fm.descent, fm.leading), x, y + notePaint.getTextSize() * 4f, notePaint);
notePaint.setColor(Color.parseColor("#FFD84315"));
// fm top线
canvas.drawLine(x - L_BIAS, y + fm.top, x + textRect.width() + L_BIAS, y + fm.top, notePaint);
notePaint.setColor(Color.parseColor("#FF00695C"));
// fm bottom线
canvas.drawLine(x - L_BIAS, y + fm.bottom, x + textRect.width() + L_BIAS, y + fm.bottom, notePaint);
notePaint.setColor(Color.parseColor("#4527A0"));
// fm ascent线
canvas.drawLine(x - L_BIAS, y + fm.ascent, x + textRect.width() + L_BIAS, y + fm.ascent, notePaint);
notePaint.setColor(Color.parseColor("#0E0822"));
// fm descent线
canvas.drawLine(x - L_BIAS, y + fm.descent, x + textRect.width() + L_BIAS, y + fm.descent, notePaint);
}
对齐文字中间¶
有了上面的基础,我们可以很快知道如何实现文字“居中对齐”。将文字的水平中心线或竖直中心线对齐到某个点。
例如绘制一个平面坐标系
绘制出2个坐标轴,然后绘制上刻度,并写上数值。
数值文字对应到刻度相应的位置上。我们主要使用Paint.getTextBounds
获取到文字的尺寸信息,再计算出合适的位置。
private void drawChart(Canvas canvas) {
final float x0 = 100;
final float y0 = 300; // 原点在画布上的坐标
final float halfLine = 5; // 刻度长度的一半
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(20);
notePaint.setStrokeWidth(2);
canvas.drawLine(x0, y0, x0 + 500, y0, notePaint); // 绘制横轴
canvas.drawLine(x0, y0, x0, y0 - 290, notePaint); // 绘制纵轴
// 绘制横轴刻度和数字
for (int i = 1; i <= 4; i++) {
int step = i * 100;
String n = String.valueOf(step);
float x = x0 + step;
canvas.drawLine(x, y0 - halfLine, x, y0 + halfLine, notePaint); // 刻度
// 文字对齐
textPaint.getTextBounds(n, 0, n.length(), textRect);
canvas.drawText(n, x - textRect.width() / 2f, y0 + textRect.height() + halfLine, textPaint);
}
// 绘制纵轴刻度和数字
for (int i = 1; i <= 2; i++) {
int step = i * 100;
String n = String.valueOf(step);
float y = y0 - step;
canvas.drawLine(x0 - halfLine, y, x0 + halfLine, y, notePaint); // 刻度
// 文字对齐
textPaint.getTextBounds(n, 0, n.length(), textRect);
canvas.drawText(n, x0 - halfLine * 2 - textRect.width(), y + textRect.height() / 2f, textPaint);
}
// 绘制原点 0
String origin = "0";
textPaint.getTextBounds(origin, 0, origin.length(), textRect);
canvas.drawText(origin, x0 - textRect.width(), y0 + textRect.height(), textPaint);
}
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~