Is your app providing a backward compatible edge-to-edge experience?
“Please make the navigation bar transparent”
— Android users (androidpolice.com)
We recommend that all apps use an edge-to-edge layout, meaning that it draws behind the system bars to use the entire width and height of the display. This means your app should do all of the following.
- Signal to the system that the app wants to draw behind the system bars.
In your Activity’s onCreate:WindowCompat.setDecorFitsSystemWindows(window, false)
- Set the system bar colors to be either transparent or translucent.
・ In theme XML:<item name=”android:statusBarColor” tools:targetApi=”21">@android:color/transparent</item>
・ In code:window.statusBarColor = transparent.
- Offset composables or views by the sizes of the system bars.
・ Compose:Modifier.safeDrawingPadding()
, etc
・ View: UseViewCompat.setOnApplyWindowInsetsListener
to obtain the insets.
To learn more about how to set up edge-to-edge on the latest Android version, check out “Designing a high quality app with the latest Android features” from Android Developer Summit ‘22.
The edge-to-edge app looks especially good in the gesture navigation mode because it can show more content using the entire screen real estate. When the device is set to the three-button navigation mode, the system automatically applies a translucent scrim to the navigation bar background.
API level 29 (Android 10) introduced gesture navigation. Different app developers might make different decisions on how or whether edge-to-edge should be set up for API level 28 and below. Some developers might set up edge-to-edge only API levels 29 and above since the older API levels only had three-button navigation. If you want to set up edge-to-edge in the most backward-compatible manner possible, here’s how.
Let’s start by listing key API levels that introduced features related to edge-to-edge.
API level 19 (Android 4.4 KitKat)
- The background of system bars can be translucent by the flags
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS / _NAVIGATION
However, it’s a translucent gradient and the appearance is quite different from that on later versions.
API level 21 (Android 5.0 Lollipop)
- The background of system bars can be translucent by the flags
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS / _NAVIGATION
Now, the color is simply translucent. - The background of the status bar can be set to transparent (or translucent) by
Window.setStatusBarColor
.
However, this is not fully usable since the icon color cannot be changed from white. - The background of the navigation bar can be translucent (or transparent) by
Window.setNavigationBarColor
.
However, this is not fully usable since the icon color cannot be changed from white.
API level 23 (Android 6.0 Marshmallow)
- The icon color on the status bar can be toggled light or dark by
WindowInsetsControllerCompat#isAppearanceLightStatusBars
.
API level 26 (Android 8.0 Oreo)
- The icon color on the navigation bar can be toggled light or dark by
WindowInsetsControllerCompat#isAppearanceLightNavigationBars
.
API level 29 (Android 10)
- Supports all the features related to edge-to-edge.
・ Gesture navigation.
・ Auto scrim on three-button navigation. Can be adjusted byWindow#isNavigationBarContrastEnforced
. - Dark mode
With these in mind, here’s one possible strategy.
API level 20 and below
- No edge-to-edge on these versions.
API level 21 and 22
- Both the status bar and the navigation bar have white icons on black translucent background.
API level 23 to 25
- The status bar has a transparent background. The icon color can be light or dark depending on the app design.
- The navigation bar has white icons on black translucent background.
API level 26 to 28
- The status bar has a transparent background. The icon color can be light or dark depending on the app design.
- The navigation bar has a translucent background. The icon color can be light or dark depending on the app design.
API level 29 and above
- Both the status bar and the navigation bar have transparent backgrounds.
- The system handles the rest. It applies a translucent background on three-button navigation. It adjusts the colors in dark mode.
Let’s see how it works on emulators running various API levels.
Here’s a code to set these all up.
This implementation should work for most apps, but here are some adjustments you might want to make depending on your app design and features.
- If your app shows images behind the status bar or the navigation bar, you might want a translucent background instead of a transparent background.
- If your app shows dark top/bottom bars in light mode, you might want to flip the icon colors.
- If your app implements custom dark mode on API level 28 and below, you have to pass its state as a parameter to this implementation and adjust some colors.
If you have any feedback on this implementation, please let me know in the comments.