Translucent SystemBars the right way – across API levels and themes

Zum Zeichnen von Rand zu Rand mit transluzenten Status- und Navigationsleisten auf v21+ mit dunklen und hellen Themes.

Dieser Artikel geht davon aus, dass Sie bereits Gestennavigation – Von Rand zu Rand gehen (I)

Da wir möchten, dass der Inhalt hinter den Systemleisten gezeichnet wird, bedeutet dies, dass

  1. Wir brauchen Durchsichtigkeit
  2. Wir brauchen entweder dunkle oder helle Scrims für die Navigationsleiste und die Statusleiste je nach aktuellem Thema.

Fähigkeit

  • Vollständig konfigurierbare statusBarColor
    Aber wir sind darauf beschränkt, dunklere Farben zu verwenden, da die statusBar-Icons weiß bleiben.
  • windowTranslucentStatus true überschreibt statusBarColor und wendet einen festen dunklen Rahmen an, der nicht geändert werden kann.
  • Fully configurable navigationBarColor
    Aber wir sind auf die Verwendung dunklerer Farben beschränkt, da die Navigationsschaltflächen weiß bleiben.
  • windowTranslucentNavigation true überschreibt navigationBarColor und wendet einen festen dunklen Rahmen an, der nicht geändert werden kann.
  • Statusleistensymbole &Navigationsleistenschaltflächen bleiben immer hell.

v23+

  • windowLightStatusBar
    Aktiviert, dass die Statusleistensymbole dunkel sind

v27+

  • windowLightNavigationBar
    Aktiviert, dass die Navigationsleistenschaltflächen dunkel sind.

Lösung

Hinweis: Wir werden eine transparente statusBarColor verwenden. Denn wir werden stattdessen AppBar verwenden, um die statusBar zu färben. Da die AppBar den Bereich der statusBar abdeckt, sollte es ausreichen, den entsprechenden Hintergrund direkt auf AppBar zu setzen.

In Ihrer Implementierung kann dies eine beliebige Ansicht sein, die sich im oberen Bereich befindet. Wenn es keine Ansicht am oberen Rand des Bildschirms gibt, können Sie stattdessen das Attribut statsuBarColor verwenden. Es wird die gleichen Ergebnisse liefern.

Basiswerte:

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:

  • Wir verzichten auf windowTranslucentStatus und windowTranslucentNavigation, da das System einen dunklen Scrim anlegt, wenn wir sie verwenden.
  • StatusBar und NavigationBar Icons bleiben weiß.
  • Das bedeutet, wir können nur dunkle Hintergründe/Scrims verwenden.

Wir haben hier 2 Möglichkeiten:

Verwenden Sie unterschiedliche Hintergründe für dunkle und helle Themen.

Im Falle des dunklen Themas wird die colorSurface dunkel/schwarz sein. Wir können eine ähnliche Farbe auch für systemBars verwenden.
Im Falle eines hellen Themas wird die colorSurface hell/weiß sein. Wir können keine ähnliche Farbe für die Systemleisten verwenden, da die Icons weiß sind.

Grundsätzlich können wir helle Systemleisten in v21-22 nicht sehr gut handhaben. So sind wir mit der Verwendung von dunklen Hintergründen nur links.

Verwenden Sie den gleichen Hintergrund für dunkle und helle Themen.

Wir können unseren Weg durch die Verwendung von dunklen Hintergründen für dunkle und helle Themen arbeiten.

Als Ergebnis wird das dunkle Thema glänzen.

Im Falle des hellen Themas:
Da dieser dunkle Hintergrund auch auf die AppBar angewendet wird (wenn wir dahinter zeichnen, was wir tun!), müssen wir ein ThemeOverlay.Dark für die AppBar verwenden. Sonst haben wir dunklen Text auf dunklem Hintergrund.

values-night

v23 – v26:

Wir können mit statusBar völlig flexibel sein, da wir die Möglichkeit haben, die Statusleistensymbole dunkel zu machen.

  • Für ein helles Thema haben wir ein helles status_bar_scrim und ein dunkles nav_bar_scrim (da die Navigationssymbole nicht dunkel sein können).
  • Für das dunkle Thema wird values-night den status_bar_scrim überschreiben, um dunkel zu sein, und nav_bar_scrim wird dem status_bar_scrim folgen, um ebenfalls dunkel zu sein.
  • Außerdem müssen wir verhindern, dass unser Widget.AppTheme.AppBar immer dunkel gestaltet wird.

values-v23

v27+:

Wir können mit navigationBar völlig flexibel sein, da wir jetzt die Möglichkeit haben, die Icons der Navigationsleiste dunkel zu machen.
Da values-v23 einen anderen status_bar_scrim und nav_bar_scrim für das Light Theme verwendet. Wir müssen hier sicherstellen, dass beide gleich sind (beide sind hell für das helle Thema und beide sind dunkel für das dunkle Thema).

Wir müssen nur den nav_bar_scrim wieder dem status_bar_scrim folgen lassen und wir sind fertig.

values-v27

Der gesamte Code kann hier gefunden werden: https://github.com/gaurav414u/MoviesInsetsDemo