Android
Canvas
Center Text
Android Development
Graphics Programming

Android Center text on canvas

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Centering text on an Android Canvas is harder than centering a rectangle because drawText uses a baseline, not the top or middle of the glyph box. The correct solution is to center horizontally with Paint.Align.CENTER and compute the vertical baseline from the font metrics.

Understand the Baseline First

The Android Canvas documentation states that the y argument of drawText is the baseline of the text being drawn. That means height / 2f is not the vertical center of the visible text, even though it looks like the obvious coordinate to use.

kotlin
canvas.drawText("Hello", width / 2f, height / 2f, paint)

This often draws the text slightly low because the baseline sits below the top of most letters and above descenders. So the problem is not "How do I draw text at the center?" but "How do I compute the baseline that makes the text appear centered?"

Horizontal Centering Is Straightforward

For horizontal placement, configure the Paint object to center text on the x coordinate.

kotlin
1private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
2    color = Color.BLACK
3    textSize = 56f
4    textAlign = Paint.Align.CENTER
5}

Once textAlign is CENTER, drawing at width / 2f centers the text horizontally. There is no need to manually subtract half the measured width for a single line if the paint alignment is already correct.

Compute Vertical Centering with Font Metrics

For vertical centering, use the font's ascent and descent. Android exposes these values through Paint.FontMetrics.

kotlin
1val fm = textPaint.fontMetrics
2val x = width / 2f
3val y = height / 2f - (fm.ascent + fm.descent) / 2f
4
5canvas.drawText("Hello Canvas", x, y, textPaint)

This is the standard single-line centering formula. It works because the midpoint between ascent and descent tells you how far the baseline should be shifted so the drawn glyph area is visually centered.

Put the Logic in a Custom View

Encapsulating the centering code in a custom view keeps the drawing behavior stable and easy to reuse.

kotlin
1class CenteredTextView(context: Context, attrs: AttributeSet? = null) : View(context, attrs) {
2
3    var label: String = "Hello Canvas"
4        set(value) {
5            field = value
6            invalidate()
7        }
8
9    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
10        color = Color.WHITE
11        textSize = 64f
12        textAlign = Paint.Align.CENTER
13    }
14
15    override fun onDraw(canvas: Canvas) {
16        super.onDraw(canvas)
17
18        val x = width / 2f
19        val fm = textPaint.fontMetrics
20        val y = height / 2f - (fm.ascent + fm.descent) / 2f
21
22        canvas.drawText(label, x, y, textPaint)
23    }
24}

This pattern is a good fit for badges, score displays, splash labels, and other simple custom-drawn text.

Multiline Text Needs a Different Approach

The font-metrics formula above is for one line. If the text can wrap, use a text layout object and center the whole text block instead of centering a single baseline.

kotlin
1val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
2    textSize = 42f
3    color = Color.BLACK
4}
5
6val layout = StaticLayout.Builder
7    .obtain(message, 0, message.length, textPaint, width)
8    .setAlignment(Layout.Alignment.ALIGN_CENTER)
9    .build()
10
11canvas.save()
12canvas.translate(0f, (height - layout.height) / 2f)
13layout.draw(canvas)
14canvas.restore()

That centers the entire paragraph block vertically and horizontally rather than trying to force one-line math onto wrapped text.

Debugging Centering Problems

If the result still looks wrong, draw guide lines through the middle of the canvas. This helps separate incorrect math from font-specific optical effects.

kotlin
1val guidePaint = Paint().apply {
2    color = Color.RED
3    strokeWidth = 2f
4}
5
6canvas.drawLine(0f, height / 2f, width.toFloat(), height / 2f, guidePaint)
7canvas.drawLine(width / 2f, 0f, width / 2f, height.toFloat(), guidePaint)

Some fonts are technically centered by metrics but still look slightly off because of glyph shapes. Guide lines make that easier to diagnose.

Common Pitfalls

  • Treating the y argument of drawText as the visible vertical center instead of the baseline.
  • Measuring text width and assuming that solves vertical centering too.
  • Applying the single-line formula to multiline or wrapped text.
  • Recreating Paint objects inside onDraw instead of reusing them.
  • Forgetting to call invalidate() when the text changes.

Summary

  • 'Canvas.drawText uses a baseline for its y coordinate.'
  • Use Paint.Align.CENTER to center text horizontally.
  • Use ascent and descent from Paint.FontMetrics to compute the centered baseline.
  • Use a layout object for multiline centered text.
  • Draw guide lines if you need to verify whether the centering math is actually correct.

Course illustration
Course illustration

All Rights Reserved.