Cómo poner la StatusBar transparente en Jetpack Compose

A
Antonio Leiva
2 min lectura

El objetivo es hacer que la TopAppBar pueda pintar por debajo de la status bar.

image

Para ello hay que seguir los siguientes pasos:

1. Poner la StatusBar transparente

El tema por defecto que se crea en un proyecto nuevo, pone la Toolbar del color primary del tema. Hay que cambiarlo para que sea transparente.

También hay que modificar la apariencia de la status bar, cuándo es lighto dark, ya que con el color primario está invertida:

window.statusBarColor = Color.Transparent.toArgb()  
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme

2. Configurar la Activity para que se reajuste con los cambios de tamaño

Para ello, en la tag activity del AndroidManifest hay que añadir:

android:windowSoftInputMode="adjustResize"

Con esto la UI cambiará de tamaño cuando se muestre el teclado virtual, usando solo el espacio que quede disponible. Esto es necesario para que no haga cosas raras cuando pintamos por debajo de las barras de navegación.

3. Activar que la activity permita pintar en todo el espacio disponible

Necesitamos llamar a la siguiente función en la activity:

override fun onCreate(savedInstanceState: Bundle?) {  
    super.onCreate(savedInstanceState)  
  
    enableEdgeToEdge()  
  
    setContent {  
        HomeScreen()  
    }  
}

4. Decirle al Scaffold que utilice la área segura de pintado

Esto valdría para cualquier Composable que tenga windowInsets en realidad, y si no los tiene los windowInsets se pueden convertir a PaddingValue.

Pero en el caso del Scaffold, no es la vista la que los consume, sino que se lo aplica al padding que luego requiere aplicar al Composable hijo.

Así que se aplica el contentWindowInsets para que use el área segura de pintado:

Scaffold(  
    contentWindowInsets = WindowInsets.safeDrawing,  
)

Y luego se le aplica al elemento interno. En este caso es un LazyVerticalGrid. Si queremos que el contenido haga scroll por debajo de las barras de navegación, entonces tiene que ir en el contentPadding.

Si no, podría ir directamente en el Modifier.padding():

Scaffold(  
    ...  
    contentWindowInsets = WindowInsets.safeDrawing,  
) { padding ->  
    LazyVerticalGrid(  
        contentPadding = padding,  
        ...
    )
}

Con esto ya conseguimos el efecto deseado.