Android Development
Paint Class
measureText()
getTextBounds()
Text Measurement

Android Paint .measureText vs .getTextBounds

Master System Design with Codemia

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

Introduction

Paint.measureText() and Paint.getTextBounds() both relate to text size, but they answer different questions. measureText() tells you how much horizontal advance the text needs when laid out. getTextBounds() gives you a tighter rectangle around the glyph shapes that would be drawn.

What measureText() Is For

Use measureText() when you care about layout width:

kotlin
val paint = Paint().apply { textSize = 48f }
val width = paint.measureText("Hello")
println(width)

This method returns a float width that reflects how much horizontal space the text consumes. It is the better choice for centering text horizontally, calculating line widths, or reserving drawing space.

What getTextBounds() Is For

getTextBounds() writes a rectangle describing the glyph bounds:

kotlin
1val paint = Paint().apply { textSize = 48f }
2val bounds = Rect()
3paint.getTextBounds("Hello", 0, 5, bounds)
4println(bounds)

That rectangle is useful when you need a tight visual box around the characters themselves, not just the advance width. It can help when aligning drawn text to custom shapes or understanding ascent and descent visually.

Why the Results Differ

The two methods do not match exactly because text layout and glyph shape are not the same thing. A font can reserve horizontal advance that is wider than the visible ink. Some characters also extend above or below the baseline differently from others.

That is why you should not expect:

  • 'measureText() width to equal bounds.width()'
  • 'getTextBounds() to be a full layout metric'

They serve different purposes.

Whitespace makes this difference easy to see. A space character affects layout width, so measureText() includes it. But a space has no visible ink, so a tight glyph rectangle from getTextBounds() does not behave like a layout measurement.

Practical Rule

Use measureText() for horizontal positioning. Use FontMetrics for vertical text layout. Use getTextBounds() when you explicitly need the drawn glyph box.

That rule avoids most confusion in custom view code.

Example: Horizontal Centering

kotlin
val text = "Hello"
val x = (viewWidth - paint.measureText(text)) / 2f
canvas.drawText(text, x, 100f, paint)

Here, measureText() is the correct method because you are solving a layout-width problem.

Example: Vertical Alignment

For vertical centering or baseline-aware placement, FontMetrics is usually the better tool:

kotlin
val metrics = paint.fontMetrics
val baseline = viewHeight / 2f - (metrics.ascent + metrics.descent) / 2f
canvas.drawText(text, 40f, baseline, paint)

This works better because Android text drawing is baseline-based, not top-left-rectangle based.

Example: Tight Box Inspection

kotlin
val bounds = Rect()
paint.getTextBounds(text, 0, text.length, bounds)
canvas.drawRect(bounds, debugPaint)

This is useful for debugging or special drawing effects, but it is not usually the primary tool for everyday text layout.

It is also handy when you want to inspect italic text or decorative fonts, because visible overhangs can make the painted glyphs extend in ways that layout width alone does not show.

Common Pitfalls

  • Using getTextBounds() when you actually need text advance width.
  • Expecting bounds.width() to equal the space needed for layout.
  • Forgetting that vertical placement usually needs FontMetrics, not just bounds.
  • Forgetting that spaces and glyph overhangs make tight bounds a poor replacement for layout metrics.
  • Comparing the two methods as if one were simply more accurate.
  • Using integer bounds when fractional layout precision matters.

Summary

  • 'measureText() is for layout width and text advance.'
  • 'getTextBounds() is for the tighter glyph bounding box.'
  • The values differ because layout width and visible ink are not the same thing.
  • Use measureText() for centering and spacing.
  • Use getTextBounds() when you specifically need glyph-shape bounds.

Course illustration
Course illustration

All Rights Reserved.