This post is the first in a small series which focuses on how developers can support gestural navigation in apps. The series will cover the following topics:

Going edge-to-edge, enabling your app to draw across the entire screen Handling visual overlaps with the system UI Handling gesture conflicts with the system gestures Common scenarios, and how to support them

Let’s get started with how apps can go ‘edge-to-edge’…

Edge-to-edge

I’m using the term edge-to-edge to describe apps expanding their window to extend across the entire screen to achieve a more immersive look. By default apps are laid out below the status bar at the top, and above the navigation bar at the bottom (together, called the system bars).

By going edge-to-edge, apps will instead be laid out behind the system bars. This is to allow your app content to shine through to create a more immersive experience for your users.

In practice this means apps need to think about two things:

Drawing behind navigation bar

The first, and most important consideration for supporting gesture navigation, is drawing behind the navigation bar. Since the navigation bar has shrunk in size and prominence, it is now strongly recommended for apps to draw behind the navigation bar when running on Android Q+ for a more compelling and modern UX.

When running on devices with Android Pie or below, drawing behind the navigation bar is optional, allowing apps to decide what makes sense. That said, nearly all the necessary APIs work back to API 21 (or AndroidX handles the differences), so the amount of extra work needed to support pre-Q devices is minimal. Users on pre-Q devices also benefit from the more immersive experience. We consider it optional solely to minimize the amount of required work and testing.

Drawing behind status bar

Secondly we look at the top of the screen, to the status bar. It is now a recommendation to draw behind the status bar if it makes sense for your content and layout. So what do we I mean by that? An examples of a layout which suits being drawn behind the status bar is full-width imagery. For developers this means that you’re using something like AppBarLayout, which sits and pins itself at the top of the screen.

Example of an app with full-width imagery behind the status bar

On the other hand, if your UI consists of a list of items with a fixed position Toolbar at the top, it may not make sense to draw behind the status bar. The same rules apply as for the navigation bar: it is totally optional when running on device before Android Q.

Implementation

There are three key steps implement drawing ‘edge-to-edge’:

1. Request to be laid out fullscreen

The first step is to tell the system to lay out our app behind the system bars (in the y-axis). The API we use for that is setSystemUiVisibility() on view, with some flags. The flags we’re interested in are:

After this our views will be laid out fullscreen behind the navigation bar.

Our app is now laid out full screen, behind the navigation bar

2. Change system bar colors

As our app is now being laid out fullscreen, we now need to change the system bar colors to allow us to see the content behind them.

Android Q

When running on Android Q, our only task is to set the system bar colors to be fully transparent:

On Android Q, the system is now responsible for handling all visual protection of the system bar content (time, icons, drag handle, etc), in all navigation modes. This means that we no longer have to do it ourselves. In practice this means the system will do one of two things:

Dynamic color adaptation

The system bar contents change color based on the content behind it. Thus if the handle is above light content it changes to a dark color. Vice versa, changing to light when in front of dark content. This is what we call dynamic color adaptation.

Dynamic color adaptation in Android Q

Translucent scrim

Alternatively, the system can apply a translucent scrim behind the system bars. The big caveat for this is that it only happens if your app declares targetSdkVersion of 29. If your app targets SDK 28 or lower, the automatic scrim will not be displayed, leaving you with a transparent navigation bar.

System-provided scrim in button navigation mode on Android Q

Both of these actions occur to ensure that the user can always see the system bar content. Which option the system chooses to use depends on a few factors. The scrim will be used if:

One of the button modes are enabled (2-button or 3-button).

In gesture navigation mode, and the device manufacturer has opted to disable dynamic color adaptation. A possible reason for this could be the performance of the device not being strong enough to handle color adaptation.

Example of scrim being used with gesture navigation

Otherwise, dynamic color adaptation will be used. The reasons listed are what are used today but they could change in the future.

Disabling system bar protection on Q

If you’d prefer to not have the system perform any automatic content protection, you can disable them by setting android:enforceNavigationBarContrast and/or android:enforceStatusBarContrast to false in your theme.

Android Pie and below

If you decide to go edge-to-edge on pre-Q devices too, you should set translucent system bar colors to act as content protection. A black scrim with 70% opacity is a good place to start for themes with dark system bars:

You may need to tweak the opacity up/down depending on the content displayed behind. For light themes, you will also want to set a light translucent color (example: #B3FFFFFF ).

Example showing a both appropriate scrims in both dark and light themes

3. Visual conflicts

After completing this, you may have noticed that some of your important views are now being laid out behind the system bars. Our third and final step is to handle any visual overlaps, which we will cover in the next blog post below.