Barras de sistema translúcidas de la manera correcta – a través de los niveles de la API y los temas

Para dibujar de borde a borde con barras de estado y navegación translúcidas en v21+ con temas oscuros y claros.

Este artículo asume que ya has pasado por Gesture Navigation- Going Edge to Edge (I)

Como queremos que el contenido se dibuje detrás de las barras del sistema, significa que

  1. Necesitamos translucidez
  2. Necesitamos mallas oscuras o claras para la barra de navegación y statusBar según el tema actual.

Capacidad

  • Color de la barra de estado totalmente configurable
    Pero estamos limitados a usar colores más oscuros ya que los iconos de la barra de estado siguen siendo de color blanco.
  • windowTranslucentStatus true anula el statusBarColor y aplica una capa oscura fija que no se puede cambiar.
  • Fully configurable navigationBarColor
    Pero estamos limitados a utilizar colores más oscuros ya que los botones de navegación siguen siendo de color blanco.
  • windowTranslucentNavigation true anula el navigationBarColor y aplica una capa oscura fija que no se puede cambiar.
  • Los iconos de la barra de estado & los botones de la barra de navegación siempre permanecen claros.

v23+

  • windowLightStatusBar
    Habilita que los iconos de la barra de estado sean oscuros

v27+

  • windowLightNavigationBar
    Habilita que los botones de la barra de navegación sean oscuros.

Solución

Nota: Usaremos un statusBarColor transparente. Porque en su lugar utilizaremos AppBar para colorear la barra de estado. Dado que la AppBar cubre el área de la statusBar, debería ser suficiente para establecer el fondo relevante a AppBar directamente.

En su implementación, esto puede ser cualquier vista que esté en la parte superior. Si no hay ninguna vista en la parte superior de la pantalla , puede utilizar en su lugar el atributo statsuBarColor. Dará los mismos resultados.

Valores base:

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:

  • Desechamos windowTranslucentStatus y windowTranslucentNavigation, ya que el sistema aplicará un scrim oscuro si los usamos.
  • Los iconos de la barra de estado y la barra de navegación siguen siendo de color blanco.
  • Es decir, sólo podemos utilizar fondos/marcas oscuras.

Tenemos 2 opciones aquí:

Utilizar fondos diferentes para temas oscuros y claros.

En caso de tema oscuro el colorSurface será oscuro/negro. Podemos usar un color similar para las systemBars también.
En caso de tema claro, el colorSurface será claro/blanco. No podemos usar un color similar para las barras del sistema ya que los iconos son blancos.

Básicamente, no podemos manejar las barras del sistema de tema claro muy bien en v21-22. Así que nos quedamos con el uso de fondos oscuros solamente.

Usar el mismo fondo para los temas oscuros y claros.

Podemos trabajar nuestro camino mediante el uso de fondos oscuros para los temas oscuros y claros.

Como resultado, el tema oscuro brillará.

En el caso del tema claro:
Dado que esta trama oscura también se aplicará a la AppBar (si estamos dibujando detrás de ella, ¡que lo estamos haciendo!), tendremos que utilizar un ThemeOverlay.Dark para la AppBar. De lo contrario, tendremos texto oscuro sobre fondo oscuro.

valores-noche

v23 – v26:

Podemos ser totalmente flexibles con statusBar ya que tenemos la capacidad de hacer que los iconos de la barra de estado se oscurezcan.

  • Para el tema claro, tendremos un status_bar_scrim claro y un nav_bar_scrim oscuro (ya que los iconos de navegación no pueden ser oscuros).
  • Para el tema oscuro, values-night anulará status_bar_scrim para que sea oscuro y nav_bar_scrim seguirá el status_bar_scrim para que sea oscuro también.
  • Además, tenemos que evitar que nuestro Widget.AppTheme.AppBar sea siempre de tema oscuro.

valores-v23

v27+:

Podemos ser totalmente flexibles con navigationBar ya que ahora tenemos la capacidad de hacer que los iconos de la barra de navegación sean oscuros.
Dado que values-v23 utiliza un status_bar_scrim y nav_bar_scrim diferentes para el tema light. Tenemos que asegurarnos aquí de que ambos son iguales (Ambos son claros para el tema claro y ambos son oscuros para el tema oscuro).

Sólo tenemos que hacer que el nav_bar_scrim siga al status_bar_scrim de nuevo y ya está.

values-v27

El código completo se puede encontrar aquí: https://github.com/gaurav414u/MoviesInsetsDemo