Translucent SystemBars the right way — across API levels and themes

Gaurav Bhola
Android Developers
Published in
4 min readJan 14, 2020

--

Goal:

To draw edge to edge with translucent status and navigation bars on v21+ with dark and light themes.

This article assumes you have already gone through Gesture Navigation- Going Edge to Edge (I)

Since we want the content to be drawn behind the system bars, it means that

  1. We need translucency
  2. We need either dark or light scrims for navigation bar and statusBar as per the current theme.

Capability

v21+

  • Fully configurable statusBarColor
    But we are limited to using darker colors as the statusBar icons remain white colored.
  • windowTranslucentStatus true will override statusBarColor and apply a fixed dark scrim that can’t be changed.
  • Fully configurable navigationBarColor
    But we are limited to using darker colors as the navigation buttons remain white colored.
  • windowTranslucentNavigation true will override navigationBarColor and apply a fixed dark scrim that can’t be changed.
  • Status bar icons & navigation bar buttons always remain light.

v23+

  • windowLightStatusBar
    Enables the statusBar icons to be dark

v27+

  • windowLightNavigationBar
    Enables the navigation bar buttons to be dark.

Solution

Note: We will be using a transparent statusBarColor. Because we will instead use AppBar to color the statusBar. Since the AppBar covers the statusBar’s area, it should be enough to set the relevant background to AppBar directly.

In your implementation, this can be any view that is on the top. If there is no view on the top of the screen , you can instead use statsuBarColor attribute. It will give the same results.

Base values:

AppBarLayout:

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/moviesAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/status_bar_scrim"
android:theme="@style/Widget.AppTheme.AppBar"
app:elevation="2dp"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/moviesToolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:title="Popular Movies" />
</com.google.android.material.appbar.AppBarLayout>

v21 — v22:

  • We ditch windowTranslucentStatus and windowTranslucentNavigation, as the system will apply a dark scrim if we use them.
  • statusBar and navigationBar icons remain white colored.
  • Means, we can only use dark backgrounds/scrims.

We got 2 options here:

1. Use different backgrounds for dark and light themes.

In case of dark theme the colorSurface will be dark/black. We can use a similar color for systemBars as well.
In case of light theme, the colorSurface will be light/white. We can’t use a similar color for systembars as the icons are white.

Basically, we can’t handle light themed system bars very well on v21–22. So we are left with using dark backgrounds only .

2. [chosen]Use same background for dark and light themes.

We can work our way by using dark backgrounds for dark and light themes.

As a result, Dark theme will shine.

In case of light theme:
Since this dark scrim will also be applied to AppBar (if we are drawing behind it, which we are!), we will have to use a ThemeOverlay.Dark for the AppBar. Else we will have dark text on dark background.

values-night

v23 — v26:

We can be fully flexible with statusBar as we have the capability to make the status bar icons go dark.

  • For light theme, we will have a light status_bar_scrim and a dark nav_bar_scrim (since the navigation icons can’t be dark).
  • For dark theme, values-night will override status_bar_scrim to be dark and nav_bar_scrim will follow the status_bar_scrim to be dark as well.
  • Also, we need to prevent our Widget.AppTheme.AppBar to be always dark themed.

values-v23

v27+:

We can be fully flexible with navigationBar as we now have the capability to make the navigation bar icons go dark.
Since values-v23 uses a different status_bar_scrim and nav_bar_scrim for light theme. We have to make sure here that both are same (Both are light for light theme and both are dark for dark theme).

We just need to make the nav_bar_scrim follow the status_bar_scrim again and we are done.

values-v27

The entire code can be found here: https://github.com/gaurav414u/MoviesInsetsDemo

--

--