How a View is measured, laid out and drawn

Views, layouts and RecyclerView Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Pick the fix

A custom progress ring changes colour every frame and the trace shows measure and layout each time. What should it call?

Options
Hint 1 of 1

Did the size or position change?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A invalidate()

Correct. Only drawing changed, so a redraw is enough.

Why not the others?
  • B requestLayout(). That re-measures and re-lays out the tree for no reason.
  • C forceLayout(). That marks the view for layout on the next pass; still unneeded.
  • D postInvalidateDelayed(0) plus requestLayout(). Adds the same unneeded layout pass.

30-second answer

Each frame that needs it runs three passes from the root. Measure: parents pass MeasureSpec constraints down and each view calls setMeasuredDimension. Layout: parents position children with layout(). Draw: each view draws itself in onDraw, then its children. requestLayout() reruns measure and layout; invalidate() only redraws.

Practise saying it · 35 s. No recording, just a timer

Explain measure, layout and draw.

Say your answer out loud, then check which of these points you covered:

  • Measure with MeasureSpec
  • Layout positions children
  • Draw in onDraw
  • invalidate vs requestLayout

Deep dive

A MeasureSpec combines a mode (EXACTLY, AT_MOST, UNSPECIFIED) with a size.

Deep or nested weighted layouts can measure children more than once, which is why flat layouts are faster.

Hardware acceleration records drawing into display lists, so invalidate() on an unchanged view is cheap.

Calling requestLayout() every frame during an animation causes jank; animate translation or alpha instead.

Common mistakes

  • Calling requestLayout when only the appearance changed.
  • Allocating objects in onDraw.
  • Nesting LinearLayouts with weights several levels deep.

Senior take & follow-ups

Name the three passes and which call triggers which.

Follow-up questions

Think of your answer first, then open the hint.

  1. invalidate vs requestLayout?

    Show hint

    invalidate redraws; requestLayout re-measures and re-lays out, then redraws.

  2. Why avoid allocation in onDraw?

    Show hint

    It runs every frame and creates garbage that triggers GC pauses.

Similar on iOS: layoutSubviews UIKit has setNeedsLayout and setNeedsDisplay, the same split.

Suggest a fix if something here is wrong or out of date.