←

Forzar dark theme en Compose con Material 3 (sin opcion al usuario)

Contexto

Casi todos los tutoriales de Compose con Material 3 ensenan a soportar light + dark + dynamic theming siguiendo isSystemInDarkTheme(). Esa es la opcion correcta para apps de proposito general. Pero hay productos donde el dark theme NO es preferencia: es decision del producto.

En una app de bloqueo de llamadas, el uso es mayormente nocturno (cuando suenan las llamadas spam). Forzar dark theme:

  1. Reduce 1 axis de configuracion en QA
  2. Elimina ~40 colores duplicados
  3. Es decision honesta: "esta app no se ve bien con fondo blanco"

Lo que aprendi

Solo declaras un colorScheme:

private val DarkColorScheme = darkColorScheme(
    primary = Primary,
    onPrimary = OnPrimary,
    primaryContainer = PrimaryVariant,
    onPrimaryContainer = OnPrimary,
    secondary = Secondary,
    onSecondary = OnSecondary,
    background = DarkBackground,
    onBackground = OnDarkBackground,
    surface = DarkSurface,
    onSurface = OnDarkSurface,
    error = Error,
    onError = OnError
)

@Composable
fun CallBlockerTheme(content: @Composable () -> Unit) {
    val colorScheme = DarkColorScheme
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as Activity).window
            window.statusBarColor = colorScheme.primary.toArgb()
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = false
        }
    }
    MaterialTheme(colorScheme = colorScheme, content = content)
}

Lo importante: isAppearanceLightStatusBars = false fuerza iconos blancos en la status bar. Si lo omites, en algunos OEMs los iconos quedan oscuros sobre fondo oscuro y no se ven.

Por que importa

A veces "no agregar la opcion" es la decision correcta. No es feature missing, es feature decision. Tu README puede decir "Dark theme always - calls happen at night anyway" y te ahorras 50% de la complejidad de theming.

El usuario que insiste en light theme no es tu publico. Esta bien.