Android: 绘制的文本如何排版
项目需求,在一个特定的矩形内绘制一段文本,并且要让文本处于矩形的正中间。
原来的方法:
先设置paint颜色,字体,字体大小等等
paint.setColor(Color.WHITE);
paint.setTextSize(fontSize);
Path textPath = new Path();
textPath.moveTo(rect_x1,textPontY);
textPath.cubicTo(rect_x1,textPontY, rect_x1,textPontY, rect_x1+rect_width,textPontY);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawTextOnPath(mailBox.getBoxNumber(), textPath, 0, 0, paint);
关键在于这个 textPontY的值如何确定。如果定位不准,达到的效果就是在水平方向上它是居中的(3点一线),在垂直方向并不是
后来想到,通过path来设置,让path沿着一个封闭的矩形,如下:
Path textPath = new Path();
textPath.moveTo(rect_x1,rect_y1);
textPath.lineTo(rect_x1 + rect_width, rect_y1);
textPath.lineTo(rect_x1 + rect_width, rect_y1+rect_height);
textPath.lineTo(rect_x1 , rect_y1+rect_height);
textPath.lineTo(rect_x1,rect_y1);
textPath.close();
然后设置 paint.setTextAlign(Paint.Align.CENTER); ,然后再 canvas.drawTextOnPath(mailBox.getBoxNumber(), textPath, 0, 0, paint);
结果证明这个想法是错误的,它并不能智能定位到矩形正中间的位置。
如何 textPontY的值如何确定 ?涉及到 “android字体大小对应的高度”
下文来自: http://www.iteye.com/topic/474526
Canvas 作为绘制文本时,使用FontMetrics对象,计算位置的坐标。
它的思路和java.awt.FontMetrics的基本相同。
FontMetrics对象
它以四个基本坐标为基准,分别为:
・FontMetrics.top
・FontMetrics.ascent
・FontMetrics.descent
・FontMetrics.bottom
该图片将如下
- PainttextPaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- textPaint.setTextSize(35);
- textPaint.setColor(Color.WHITE);
- //FontMetrics对象
- FontMetricsfontMetrics=textPaint.getFontMetrics();
- Stringtext="abcdefghijklmnopqrstu";
- //计算每一个坐标
- floatbaseX=0;
- floatbaseY=100;
- floattopY=baseY+fontMetrics.top;
- floatascentY=baseY+fontMetrics.ascent;
- floatdescentY=baseY+fontMetrics.descent;
- floatbottomY=baseY+fontMetrics.bottom;
- //绘制文本
- canvas.drawText(text,baseX,baseY,textPaint);
- //BaseLine描画
- PaintbaseLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);>
- baseLinePaint.setColor(Color.RED);
- canvas.drawLine(0,baseY,getWidth(),baseY,baseLinePaint);
- //Base描画
- canvas.drawCircle(baseX,baseY,5,baseLinePaint);
- //TopLine描画
- PainttopLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- topLinePaint.setColor(Color.LTGRAY);
- canvas.drawLine(0,topY,getWidth(),topY,topLinePaint);
- //AscentLine描画
- PaintascentLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- ascentLinePaint.setColor(Color.GREEN);
- canvas.drawLine(0,ascentY,getWidth(),ascentY,ascentLinePaint);
- //DescentLine描画
- PaintdescentLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- descentLinePaint.setColor(Color.YELLOW);
- canvas.drawLine(0,descentY,getWidth(),descentY,descentLinePaint);
- //ButtomLine描画
- PaintbottomLinePaint=newPaint(Paint.ANTI_ALIAS_FLAG);
- bottomLinePaint.setColor(Color.MAGENTA);
- canvas.drawLine(0,bottomY,getWidth(),bottomY,bottomLinePaint);
由上可得出一个常识:drawText绘制文本时,是从baseLine这个位置开始的,并不简单认为是从文本的左下角开始绘制。
由上图可以分析出:
float textPontY = rect_y1 + (rect_height - temp)/2.0f + temp - fontMetrics.bottom;
把 textPointY设置成这样的值,就对了!