Interview QuestionPractical QuestionFollow-up Questions

View Lifecycle

skydovesJaewoong Eum (skydoves)||10 min read

View Lifecycle

Every Android View goes through a series of stages from creation to destruction. The system calls specific methods as the View is attached to a window, measured, laid out, drawn, and eventually detached. Understanding these stages is fundamental for building custom views, managing resources tied to a View's visibility, and avoiding drawing or measurement bugs. By the end of this lesson, you will be able to:

  • Trace the View lifecycle from instantiation through detachment.
  • Explain the measure, layout, and draw pipeline and when each method is called.
  • Describe the role of onAttachedToWindow() and onDetachedFromWindow() in resource management.
  • Identify how invalidate() and requestLayout() trigger specific phases of the pipeline.
  • Apply lifecycle awareness in custom views to avoid leaks and unnecessary work.

Attachment to the Window

A View is instantiated either programmatically or by the layout inflater when parsing XML. At this point, the View exists as a Kotlin/Java object but is not part of any window or visible hierarchy. No measurement or drawing has occurred.

Custom views typically implement multiple constructors: a single argument constructor (Context) for programmatic creation, a two argument constructor (Context, AttributeSet) for XML inflation, and a three argument constructor (Context, AttributeSet, defStyleAttr) for theme customization. The XML inflater uses the two argument form and passes the declared attributes for parsing.

When the View is added to a ViewGroup that is attached to a window, the system calls onAttachedToWindow(). This is the first point where the View has access to a display surface and can register for system callbacks. It is the right place to start animations, register listeners, or acquire resources that depend on the View being part of a live hierarchy.

override fun onAttachedToWindow() {
    super.onAttachedToWindow()
    sensorManager.registerListener(
        this, accelerometer, SensorManager.SENSOR_DELAY_UI
    )
}

A View can be attached and detached multiple times during the life of its hosting Activity or Fragment. Adding a View to a parent calls onAttachedToWindow(); removing it calls onDetachedFromWindow(). RecyclerView, for example, detaches and reattaches item views as they scroll in and out of the viewport.

Measure and Layout

After attachment, the system runs the measure and layout passes. The parent ViewGroup calls measure() on each child, which delegates to onMeasure(). The child calculates its desired width and height based on the MeasureSpec constraints provided by the parent and calls setMeasuredDimension() to report the result.

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val desiredWidth = calculateContentWidth()
    val desiredHeight = calculateContentHeight()

    val width = resolveSize(desiredWidth, widthMeasureSpec)
    val height = resolveSize(desiredHeight, heightMeasureSpec)

    setMeasuredDimension(width, height)
}

MeasureSpec encodes both a size and a mode. EXACTLY means the parent has determined the exact size. AT_MOST means the child can be up to the specified size. UNSPECIFIED means there is no constraint (common in ScrollView).

After measurement, the parent calls layout() on each child, which triggers onLayout(). For a leaf View, onLayout() is typically empty. For a ViewGroup, onLayout() positions each child by calling child.layout(left, top, right, bottom). The layout pass runs top down through the hierarchy, with each parent placing its children based on the measured dimensions.

This interview continues for subscribers

Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.

Become a Sponsor