概述
1.基线
基线相当于小学写英语的四格线的第三条线,只要基线的位置确定了,那么绘制的文字的位置就可以确定了。
2.canvas.drawText()方法
(1)Canvas与基线
现在就以最简单的方法为例:
public void drawText(String text, float x, float y, Paint paint)
传进去的x和y很容易被误解为绘制文字的矩形的左上角,其实y是基线的位置。
(2)简单的实例
将基线和文字同时在图上绘制,看一看基线和绘制文字起点坐标的关系。
//绘制文字
canvas.drawText("Boy",baseX,baseY,paint);
//绘制基线
canvas.drawLine(baseX,baseY,1500,baseY,paint);
(4)setTextAlign(Align align)
从前面知道y轴是基线的位置,现在需要知道x轴代表文字所在矩形的相对位置,有三个值:左中右。分别来看一下效果
//绘制文字 绘制基线
paint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("BoyGirl",baseX,baseY,paint);
canvas.drawLine(baseX,baseY,1500,baseY,paint);
baseY+=200;
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("GirlsGirls",baseX,baseY,paint);
canvas.drawLine(baseX,baseY,1500,baseY,paint);
baseY+=200;
paint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("OurLove",baseX,baseY,paint);
canvas.drawLine(baseX,baseY,1500,baseY,paint);
drawText的四线格和FontMetrics
在绘制Text的时候,其实是有5条线,除了之前介绍的基线,还有ascent,descent,top,bottom,它们的含义分别为:
ascent:系统建议的,绘制字符时,字符应当的最高高度所在线
descent:系统建议的,绘制字符时,字符应当的最低高度所在线
top:可绘制的最高高度所在线
bottom:可绘制的最低高度所在线
2.FontMetrics
(1)fontMetrics介绍
从前面可知,baseLine是由于绘制文字时指定的y决定的,其他的四条线则是由系统提供的FontMetrics这个类计算出来的,这个类下有四个成员变量:
FontMetrics:ascent FontMetrics:descent FontMetrics:top FontMetrics:bottom
它们意义和值的计算如下:
ascent = ascent线的y坐标 - baseline线的y坐标;
descent = descent线的y坐标 - baseline线的y坐标;
top = top线的y坐标 - baseline线的y坐标;
bottom = bottom线的y坐标 - baseline线的y坐标;
从上述的式子,可以得到计算四条线的方法:
ascent线Y坐标 = baseline线的y坐标 + fontMetric.ascent;
descent线Y坐标 = baseline线的y坐标 + fontMetric.descent;
top线Y坐标 = baseline线的y坐标 + fontMetric.top;
bottom线Y坐标 = baseline线的y坐标 + fontMetric.bottom;
(3)获取FontMetrics对象
Paint paint = new Paint();
Paint.FontMetrics fm = paint.getFontMetrics();
Paint.FontMetricsInt fmInt = paint.getFontMetricsInt();
FontMetricsInt的意义和FontMetrics一样,只是它的四个成员变量都是int类型的,而FontMetrics的四个成员变量都是float类型的。
(4)实例:计算Text的四线格
//获取
Paint.FontMetrics fontMetrics=paint.getFontMetrics();
canvas.drawText("MyBoy,are you OK?",baseX,baseY,paint);
//绘制基线
paint.setColor(Color.GRAY);
canvas.drawLine(baseX,baseY,1500,baseY,paint);
//绘制top
float top=baseY+fontMetrics.top;
paint.setColor(Color.BLUE);
canvas.drawLine(baseX,top,1500,top,paint);
//绘制bottom
float bottom=baseY+fontMetrics.bottom;
paint.setColor(Color.BLACK);
canvas.drawLine(baseX,bottom,1500,bottom,paint);
//绘制ascent
float ascent=baseY+fontMetrics.ascent;
paint.setColor(Color.YELLOW);
canvas.drawLine(baseX,ascent,1500,ascent,paint);
//绘制descent
float descent=baseY+fontMetrics.descent;
paint.setColor(Color.GREEN);
canvas.drawLine(baseX,descent,1500,descent,paint);
所绘制文字宽度、高度和最小矩形获取
1.字符串所占宽度和高度
(1)高度和宽度
Paint.FontMetrics metrics=paint.getFontMetrics();
//获取字符串所占的高度
float top=baseY+metrics.top;
float bottom=baseY+metrics.bottom;
float height=top-bottom;
//获取字符串所占的宽度
float width=paint.measureText("ddasda");
(2)获取最小矩形
获取最小矩形使用的是系统提供的方法:
/**
* 获取指定字符串所对应的最小矩形,以(0,0)点所在位置为基线
* @param text 要测量最小矩形的字符串
* @param start 要测量起始字符在字符串中的索引
* @param end 所要测量的字符的长度
* @param bounds 接收测量结果
*/
public void getTextBounds(String text, int start, int end, Rect bounds);
//获取字符串所占的宽度
float width=paint.measureText(msg);
//获取最小矩形
paint.getTextBounds(msg,0,msg.length(),rect);
Log.e("Draw",rect.toString());
Log.e("Draw","高度:"+height+",宽度:"+width);
Log.e("Draw","最小矩形:宽 "+(rect.right-rect.left)+",高 "+(rect.bottom-rect.top));
可以看到得到的最小矩形,它的起点的纵坐标是负值,这是因为前面在使用getTextBounds()方法的时候,没有为它规定基线,所以它是以(0,0)为基线得到的。最小矩形的实际位置离(0,0)还有一段距离,需要再次移动baseLine这段距离。
//文字
Paint.FontMetricsInt metrics=paint.getFontMetricsInt();
String msg="MyBoys";
canvas.drawText(msg,baseX,baseY,paint);
//绘制的文字所在的矩形 宽 高
int width=(int)paint.measureText(msg);
int height=metrics.bottom-metrics.top;
paint.setColor(Color.GREEN);
RectF rectF=new RectF(baseX,metrics.top+baseY,baseX+width,metrics.bottom+baseY);
canvas.drawRect(rectF,paint);
//绘制最小矩形
paint.setColor(Color.BLUE);
Rect oriRect=new Rect();
paint.getTextBounds(msg,0,msg.length(),oriRect);
oriRect.top=baseY+oriRect.top;
oriRect.bottom=baseY+oriRect.bottom;
oriRect.left=baseX+oriRect.left;
oriRect.right=baseX+oriRect.right;
canvas.drawRect(oriRect,paint);