android中自定義控件,自己繪制文字canvas.drawText()的時候,怎樣才能讓文字垂直居中那?
drawText()的方法說明

也就是使用paint畫筆在(X,Y)處進行繪制,X為橫向坐標的起始位置,Y為縱向坐標的文本的baseline的坐標值。
首先必須了解下文本的五線譜

其中:
ascent : 該距離是從所繪字符的baseline之上至該字符所繪制的最高點。
descent: 該距離是從所繪字符的baseline之下至該字符所繪制的最低點。
top: 該距離是從所繪字符的baseline之上至可繪制區域的最高點。
bottom: 該距離是從所繪字符的baseline之下至可繪制區域的最低點。
leading: 為文本的線之間添加額外的空間,這是官方文檔直譯,debug時發現一般都為0.0,該值也是系統推薦的。
特別注意: ascent和top都是負值,而descent和bottom:都是正值,這些值都是基於baseline為坐標0的相對值。
Android文字繪制是相對於基線繪制的,也就是圖中的紅線,而top+bottom的長度就等於字體高度,即等於|top|+|bottom|絕對值
實際繪制取決於基線上一個點來繪制文字,而這個點有三種分別對應為left, center, right如下圖:

而drawText()方法中x,y坐標所指的點就是上圖基線上三個點中的一個,具體是哪一個根據paint的setTextAlign()方法設置。默認為left
看代碼:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
areaRect = canvas.getClipBounds();
Log.d("Linghu","========linghu="+areaRect.width()+","+areaRect.height());
// paint.setColor(Color.parseColor("#0000ff"));
// canvas.drawText(conStr, 0, 0, paint);
paint.setColor(Color.parseColor("#ff0000"));
canvas.drawText(conStr, 0, (areaRect.bottom+areaRect.top)/2.0f - metrics.descent+(metrics.bottom-metrics.top)/2, paint);
paint.setColor(Color.parseColor("#0000ff"));
canvas.drawLine(0, areaRect.height()/2, areaRect.right, areaRect.height()/2 +1, paint);
// paint.setColor(Color.parseColor("#00ff00"));
Log.d("Linghu","========bottom="+metrics.bottom+",descent="+metrics.descent+",top="+metrics.top+",ascent="+metrics.ascent);
// int base = (int)(metrics.bottom - metrics.descent);
// canvas.drawText(conStr, 0, base, paint);
}

計算baseline值的過程大致如下:
第一: 獲取View的中心位置
(areaRect.top+areaRect.bottom)/2;
第二: 中心位置下移半個字體的高度,此時baseline的位置是圖的文字
+(metrics.bottom - metrics.top)/2;
第三: 上移descent,達到文字的最終位置:
-descent;
(areaRect.top+areaRect.bottom)/2 +(metrics.bottom - metrics.top)/2 - descent;

經過這三步就使得文字在控件的居中位置了。這里paint的TextAlign是默認值top,因為這種情況比較多;如果設置TextAlign=center,那就簡單多了,具體如下:
(areaRect.top+areaRect.bottom)/2-(metrics.top + metrics.bottom)/2
希望對大家有所幫助。
