Display content edge-to-edge in your app

Try the Compose way
Jetpack Compose is the recommended UI toolkit for Android. Learn how to work with edge-to-edge in Compose.

You can make your app display edge-to-edge—using the entire width and height of the display—by drawing behind the system bars. The system bars are the status bar and the navigation bar.

To implement an edge-to-edge layout, your app must do the following:

  • Draw behind the navigation bar to achieve a more compelling and modern user experience.
  • Draw behind the status bar if it makes sense for your content and layout, such as in the case of full-width imagery. To do this, use APIs such as AppBarLayout, which defines an app bar pinned to the top of the screen.
Figure 1. System bars in an edge-to-edge layout.

To implement an edge-to-edge layout in your app, perform the following steps:

  1. Enable the edge-to-edge display.
  2. Handle any visual overlaps.
An image showing an app with imagery behind the status bar
Figure 2. Example of an app with imagery behind the status bar.

Enable the edge-to-edge display.

You can enable the edge-to-edge display in your app by calling enableEdgeToEdge in onCreate of your Activity. It should be called before setContentView.

Kotlin

  override fun onCreate(savedInstanceState: Bundle?) {
    enableEdgeToEdge()
    super.onCreate(savedInstanceState)
    ...
  }

Java

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    EdgeToEdge.enable(this);
    super.onCreate(savedInstanceState);
    ...
  }

By default, enableEdgeToEdge makes the system bars transparent, except on 3-button navigation mode where the status bar gets a translucent scrim. The colors of the system icons and the scrim are adjusted based on the system light or dark theme.

The enableEdgeToEdge method automatically declares that the app should be laid out edge-to-edge and adjusts the colors of the system bars. See "Manually set up the edge-to-edge display" if this is necessary for any reason.

Handle overlaps using insets

After you enable the edge-to-edge display, some of your app's views might draw behind the system bars, as shown in figure 3.

You can address overlaps by reacting to insets, which specify which parts of the screen intersect with system UI such as the navigation bar or the status bar. Intersecting can mean displaying above the content, but it can also inform your app about system gestures.

The types of insets that apply to displaying your app edge-to-edge are:

  • System bars insets: best for views that are tappable and that must not be visually obscured by the system bars.

  • System gesture insets: for gesture-navigational areas used by the system that take priority over your app.

System bars insets

System bar insets are the most commonly used type of insets. They represent the area where the system UI displays in the Z-axis above your app. They are best used to move or pad views in your app that are tappable and that must not be visually obscured by the system bars.

For example, the floating action button (FAB) in figure 3 is partially obscured by the navigation bar:

An image showing edge-to-edge implemented, but the nav bar is covering the FAB
Figure 3. Navigation bar overlapping an FAB in an edge-to-edge layout.

To avoid this kind of visual overlap in either gesture mode or button mode, you can increase the view's margins using getInsets(int) with WindowInsetsCompat.Type.systemBars().

The following code example shows how to implement system bar insets:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets ->
  val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
  // Apply the insets as a margin to the view. This solution sets
  // only the bottom, left, and right dimensions, but you can apply whichever
  // insets are appropriate to your layout. You can also update the view padding
  // if that's more appropriate.
  v.updateLayoutParams<MarginLayoutParams>(
      leftMargin = insets.left,
      bottomMargin = insets.bottom,
      rightMargin = insets.right,
  )

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> {
  Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
  // Apply the insets as a margin to the view. This solution sets only the
  // bottom, left, and right dimensions, but you can apply whichever insets are
  // appropriate to your layout. You can also update the view padding if that's
  // more appropriate.
  MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
  mlp.leftMargin = insets.left;
  mlp.bottomMargin = insets.bottom;
  mlp.rightMargin = insets.right;
  v.setLayoutParams(mlp);

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

If you apply this solution to the example shown in figure 3, it results in no visual overlap in button mode, as shown in figure 4:

An image showing a translucent nav bar not covering the FAB
Figure 4. Resolving visual overlap in button mode.

The same applies to gesture navigation mode, as shown in figure 5:

An image showing edge-to-edge with gesture navigation
Figure 5. Resolving visual overlap in gesture navigation mode.

System gesture insets

System gesture insets represent the areas of the window where system gestures take priority over your app. These areas are shown in orange in figure 6:

An image showing system gesture insets
Figure 6. System gesture insets.

Like the system bar insets, you can avoid overlapping the system gesture insets using getInsets(int) with WindowInsetsCompat.Type.systemGestures().

Use these insets to move or pad swipeable views away from the edges. Common use cases include bottom sheets, swiping in games, and carousels implemented using ViewPager2.

On Android 10 or later, system gesture insets contain a bottom inset for the home gesture, and a left and right inset for the back gestures:

An image showing system gesture inset measurements
Figure 7. System gesture inset measurements.

The following code example shows how to implement system gesture insets:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.updatePadding(insets.left, insets.top, insets.right, insets.bottom)

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
    Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures());
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.setPadding(insets.left, insets.top, insets.right, insets.bottom);

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

Immersive mode

Some content is best experienced in full screen, giving the user a more immersive experience. You can hide the system bars an for immersive mode using the WindowInsetsController and WindowInsetsControllerCompat libraries:

Kotlin

val windowInsetsController =
      WindowCompat.getWindowInsetsController(window, window.decorView)

// Hide the system bars.
windowInsetsController.hide(Type.systemBars())

// Show the system bars.
windowInsetsController.show(Type.systemBars())

Java

Window window = getWindow();
WindowInsetsControllerCompat windowInsetsController =
      WindowCompat.getWindowInsetsController(window, window.getDecorView());
if (windowInsetsController == null) {
    return;
  }
// Hide the system bars.
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());

// Show the system bars.
windowInsetsController.show(WindowInsetsCompat.Type.systemBars());

Refer to Hide system bars for immersive mode for more information about implementing this feature.

Additional resources

See the following references for more information about WindowInsets, gesture navigation, and how insets work: