在自定义View的时候使用drawText来绘制字符。
drawText(String text, float x, float y,Paint paint)
默认情况根据参数x轴位置,从左至右绘制。以下为例,两条红线分别为View的x,y轴的中心线。
通常可以设置Paint的TextAlign,让字符是从x轴的左边|中间|右边开始绘制文字。
/**
LEFT (0),
CENTER (1),
RIGHT (2);
**/
mTextPaint.setTextAlign(Paint.Align.CENTER);
一眼望去,上图所绘制的文字"哈哈哈"文字已经超出了中心线的。实际文字Y轴坐标参数和中心线位置都是相同的。虽然看来偏差不大,但总感觉不太舒服。
如上图所示,在drawText时Y轴就是按照BaseLine(基线)来绘制的。所以绘制完了以后总会留那么一点出来。
解决办法:
public void getTextBounds(String text, int start, int end, Rect bounds)
使用此方法可以计算出字符的最小包裹区域:
String txt = "哈哈";
Rect txtRec = new Rect();
txtRec.height();
mTextPaint.getTextBounds(txt,0,txt.length(),txtRec);
canvas.drawText(txt,centerX,centerY,mTextPaint);
int txtCenterX = txtRec.width() / 2;
int left = centerX - txtCenterX;
int top = centerY +txtRec.bottom-txtRec.height();
int right = centerX+txtCenterX;
int bottom = centerY + txtRec.bottom;
//bottom线
canvas.drawLine(left, bottom,right, bottom,mLinePaint);
//left线
canvas.drawLine(left,bottom,left,top,mLinePaint);
//top线
canvas.drawLine(left,top,right,top,mLinePaint);
//right线
canvas.drawLine(right,top,right,bottom,mLinePaint);
而我们只需要在原有Y轴上减去bottom的距离让坐标上移,绘制出来的效果完全在中心线上。
canvas.drawText(txt,centerX,centerY-txtRec.bottom,mTextPaint);
还可以使用measureText()计算字符的宽度,该宽度包括字符左右边距,会比getTextBounds()计算出来的长一点。
mTextPaint.measureText()
文字垂直居中,只需要:
canvas.drawText(txt,centerX,centerY+txtRec.height()/2-txtRec.bottom,mTextPaint);
参考:
自定义View之绘图篇(四):baseLine和FontMetrics
Android paint的drawText()的正确使用方式