The problem is that while you can easily set a horizontal alignment for your TextPaint (via Paint.Align),the
vertical alignment is tricky. That's because Canvas.drawText() starts drawing at the baseline of your set Y-
coordinate, instead of the center.
If you only knew the height of the text, then you could center it yourself - but getting the height is tricky!
TextPaint.getTextBounds() doesn't work quite right because it gives you the minimal bounding rectangle,
not the height that the TextPaint draws. For example, if your text has no ascenders/descenders, then the
measured height is smaller than it will draw (since it will still account for the possibility of them).
The way I've found to get the height of the TextPaint is to use ascent() and descent(). These measure the
size above/below the text's baseline. Combined, they add up to the total height of the drawn text. You can
then use some math to center the draw on the baseline - here's a version of onDraw() that does it correctly*:
or u can use Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt(); to get the descent and ascent of textPaint
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
TextPaint textPaint = new TextPaint();
textPaint.setColor(Color.WHITE);
textPaint.setTextAlign(Paint.Align.CENTER);
float textHeight = textPaint.descent() - textPaint.ascent();
float textOffset = (textHeight / 2) - textPaint.descent();
or
Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
float textHeight = fontMetrics.decent-fontMetrics.ascent;
float textOffset = (textHeight/2)-fontMetrics.dscent;
RectF bounds = new RectF(0, 0, getWidth(), getHeight());
canvas.drawOval(bounds, paint);
canvas.drawText("42", bounds.centerX(), bounds.centerY() + textOffset, textPaint);
}