前言
項(xiàng)目中碰到一個(gè)問(wèn)題,需要在自定義View的中央繪制文字;算出了文字的高度,寬度,用自定義View的中心點(diǎn)坐標(biāo),減去1/2的高度(寬度)來(lái)作為起始坐標(biāo)繪制文字,結(jié)果發(fā)現(xiàn)文字垂直方向不居中顯示。
代碼分析
出錯(cuò)的代碼如下:
//測(cè)量字符串長(zhǎng)度
float textLength = textPaint.measureText(text);
//把文本畫在圓心居中
canvas.drawText(text, x - textLength/2, y+mTextSize/2, textPaint);
從效果上看,水平方向是居中的,但是垂直方向上的偏移量有問(wèn)題,這里的偏移量是通過(guò)textSize獲取的。
Android文本繪制原理介紹

Text繪制原理
android中的文字繪制是相對(duì)于圖中的Baseline繪制的。bottom-top的高度是字體高度(textSize)
-
drawText函數(shù)說(shuō)明
drawText函數(shù)說(shuō)明
這里的(x, y)的具體位置是Baseline上三個(gè)點(diǎn)中的一個(gè)(具體根據(jù)TextAlign的取值確定)
Baseline中的(x,y)
代碼實(shí)現(xiàn)
所以這個(gè)問(wèn)題的根源就是我們drawText中的x,y的含義弄錯(cuò)了;可用如下代碼找到Baseline位置,并居中顯示
Rect rect = new Rect(100,100,500,500);//畫一個(gè)矩形
Paint rectPaint = new Paint();
rectPaint.setColor(Color.BLUE);
rectPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(rect, rectPaint);
Paint textPaint = new Paint();
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(50);
textPaint.setStyle(Paint.Style.FILL);
//該方法即為設(shè)置基線上那個(gè)點(diǎn)到底是left,center,還是right 這里我設(shè)置為center
textPaint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float top = fontMetrics.top;//為基線到字體上邊框的距離,即上圖中的top
float bottom = fontMetrics.bottom;//為基線到字體下邊框的距離,即上圖中的bottom
int baseLineY = (int) (rect.centerY() - top/2 - bottom/2);//基線中間點(diǎn)的y軸計(jì)算公式
canvas.drawText("你好世界",rect.centerX(),baseLineY,textPaint);

圖示
baseLineY也可以這樣計(jì)算:
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)) ;
//((textPaint.descent() + textPaint.ascent()) / 2) is the distance from the baseline to the center.

