Translucent SystemBars på rätt sätt – över API-nivåer och teman

För att rita kant i kant med translucenta status- och navigeringsfält i v21+ med mörka och ljusa teman.

Denna artikel förutsätter att du redan har gått igenom Gesture Navigation- Going Edge to Edge (I)

Då vi vill att innehållet ska ritas bakom systemfältet betyder det att

  1. Vi behöver translucency
  2. Vi behöver antingen mörka eller ljusa scrims för navigeringsfältet och statusBar enligt det aktuella temat.

Förmåga

  • Fullt konfigurerbar statusBarColor
    Men vi är begränsade till att använda mörkare färger eftersom ikonerna i statusBar förblir vitfärgade.
  • windowTranslucentStatus true åsidosätter statusBarColor och tillämpar en fast mörk scrim som inte kan ändras.
  • Fullt konfigurerbar navigationBarColor
    Men vi är begränsade till att använda mörkare färger eftersom navigeringsknapparna förblir vitfärgade.
  • windowTranslucentNavigation true åsidosätter navigationBarColor och tillämpar en fast mörk scrim som inte kan ändras.
  • Ikoner i statusfältet & navigationsfältets knappar förblir alltid ljusa.

v23+

  • windowLightStatusBar
    Aktiverar ikonerna i statusfältet att vara mörka

v27+

  • windowLightNavigationBar
    Aktiverar knapparna i navigationsfältet att vara mörka.

Lösning

Notera: Vi kommer att använda en transparent statusBarColor. Eftersom vi istället kommer att använda AppBar för att färga statusBar. Eftersom AppBar täcker statusBars område borde det räcka att ställa in den relevanta bakgrunden till AppBar direkt.

I din implementering kan detta vara vilken vy som helst som ligger överst. Om det inte finns någon vy högst upp på skärmen , kan du istället använda statsuBarColor-attributet. Det ger samma resultat.

Basvärden:

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:

  • Vi dikterar windowTranslucentStatus och windowTranslucentNavigation, eftersom systemet kommer att tillämpa en mörk scrim om vi använder dem.
  • statusBar och navigationBar ikoner förblir vitfärgade.
  • Menar, vi kan bara använda mörka bakgrunder/kransar.

Vi har 2 alternativ här:

Använd olika bakgrunder för mörka och ljusa teman.

Vid mörkt tema kommer colorSurface att vara mörk/svart. Vi kan använda en liknande färg för systemBars också.
Vid ljust tema kommer colorSurface att vara ljus/vit. Vi kan inte använda en liknande färg för systembars eftersom ikonerna är vita.

Basically, we can’t handle light thema system bars very well on v21-22. Så vi är kvar med att endast använda mörka bakgrunder .

Använd samma bakgrund för mörka och ljusa teman.

Vi kan arbeta oss fram genom att använda mörka bakgrunder för mörka och ljusa teman.

Som resultat kommer det mörka temat att lysa.

För det ljusa temat:
Då den mörka bakgrunden även kommer att appliceras på AppBar (om vi ritar bakom den, vilket vi gör!), måste vi använda en ThemeOverlay.Dark för AppBar. Annars får vi mörk text på mörk bakgrund.

values-night

v23 – v26:

Vi kan vara helt flexibla med statusBar eftersom vi har möjlighet att få ikonerna i statusfältet att bli mörka.

  • För ljusa teman kommer vi att ha en ljus status_bar_scrim och en mörk nav_bar_scrim (eftersom navigationsikonerna inte kan vara mörka).
  • För mörkt tema kommer values-night att åsidosätta status_bar_scrim så att den blir mörk och nav_bar_scrim kommer att följa status_bar_scrim så att den också blir mörk.
  • Också måste vi förhindra att vår Widget.AppTheme.AppBar alltid har ett mörkt tema.

values-v23

v27+:

Vi kan vara helt flexibla med navigationBar eftersom vi nu har möjlighet att låta ikonerna i navigationsfältet bli mörka.
Då values-v23 använder en annan status_bar_scrim och nav_bar_scrim för ljusa teman. Vi måste här se till att båda är likadana (båda är ljusa för ljust tema och båda är mörka för mörkt tema).

Vi behöver bara se till att nav_bar_scrim följer status_bar_scrim igen och vi är klara.

values-v27

Helheten av koden kan hittas här: https://github.com/gaurav414u/MoviesInsetsDemo