Android
RelativeLayout
Z order
view hierarchy
Android development

Defining Z order of views of RelativeLayout in Android

Master System Design with Codemia

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

Introduction

In a RelativeLayout, overlapping child views are usually drawn according to child order: later children are drawn on top of earlier ones. That simple rule solves many cases, but modern Android also adds elevation and translation-based depth effects that can change how views appear above one another. The right solution depends on whether you need static stacking, runtime reordering, or real Material-style elevation.

Default Z Order in RelativeLayout

When child views overlap, the normal rule is:

  • children declared earlier are drawn first
  • children declared later are drawn on top

Example:

xml
1<RelativeLayout
2    xmlns:android="http://schemas.android.com/apk/res/android"
3    android:layout_width="match_parent"
4    android:layout_height="match_parent">
5
6    <View
7        android:id="@+id/redBox"
8        android:layout_width="120dp"
9        android:layout_height="120dp"
10        android:background="#FF0000" />
11
12    <View
13        android:id="@+id/blueBox"
14        android:layout_width="120dp"
15        android:layout_height="120dp"
16        android:layout_marginLeft="40dp"
17        android:layout_marginTop="40dp"
18        android:background="#0000FF" />
19</RelativeLayout>

Here, blueBox appears above redBox because it is declared later.

The Simplest Static Solution

If you only need one view to appear above another in a static layout, reorder the XML children so the topmost view is declared later.

That is the oldest and simplest solution, and for many RelativeLayout UIs it is still enough.

Runtime Reordering With bringToFront

If the stacking order needs to change dynamically, use bringToFront().

kotlin
1val target = findViewById<View>(R.id.redBox)
2target.bringToFront()
3target.parent?.requestLayout()
4target.invalidate()

This is useful when one view should temporarily move above another after a user action.

In older layouts, calling requestLayout() and invalidate() after bringToFront() helps make the update visible reliably.

Elevation on Modern Android

On newer Android versions, elevation and translationZ provide a more explicit depth model.

xml
1<View
2    android:id="@+id/cardView"
3    android:layout_width="120dp"
4    android:layout_height="120dp"
5    android:elevation="8dp"
6    android:background="#FFFFFF" />

Or in code:

kotlin
view.elevation = 8f
view.translationZ = 4f

This is more than just draw order. It participates in shadows and Material-style depth behavior.

Which Rule Wins

In practice:

  • child order affects drawing order
  • elevation affects visual depth on supported Android versions
  • runtime calls such as bringToFront() can alter stacking dynamically

If the UI is simple, child order is usually easiest to reason about. If the design uses Material surfaces, elevation is often the better tool.

Visual order and touch behavior are related, but they are not exactly the same concept. A view that appears on top may still not respond as expected if clickability, parent interception, or visibility flags are misconfigured.

So if a view looks correct but touch events feel wrong, do not assume the z-order rule is the only issue.

A Practical Rule for Older RelativeLayout Code

For classic overlapping layouts:

  1. set the XML child order intentionally
  2. use bringToFront() for temporary runtime changes
  3. use elevation only if the UI is on a modern platform path and the visual design needs it

That keeps the stacking model simple instead of mixing every mechanism at once.

Common Pitfalls

  • Assuming RelativeLayout stacking is magic instead of mostly child-order based.
  • Mixing bringToFront() and elevation without a clear reason.
  • Forgetting that later XML children are usually drawn above earlier ones.
  • Debugging touch problems as if they were purely visual z-order problems.
  • Using RelativeLayout for heavily layered modern UI when another container may express the design more clearly.

Summary

  • In RelativeLayout, later children are usually drawn on top of earlier ones.
  • Reordering XML children is the simplest static z-order control.
  • Use bringToFront() for runtime stacking changes.
  • Use elevation and translationZ when you need modern visual depth behavior.
  • Keep visual order and touch handling separate in your debugging model.

Course illustration
Course illustration

All Rights Reserved.