Bradleycorn
01/26/2025, 6:05 PMBradleycorn
01/26/2025, 6:06 PMenableEdgeToEdge()
. It's a pretty standard/basic setup, and uses WindowInsets appropriately to display behind system ui's and add appropriate content padding.
However, I have screens with various content and need to change the system bar content color, "on the fly". Here's an example (assuming the device is in light mode and I'm using a "light" theme) ...
My top level screens contain a TopAppBar
, while "child" screens do not contain an app bar. My App bar has a dark background color. So when showing a top level screen with an App Bar, I'd like the system bar content to be light/white. But when showing a "child" screen with no App Bar, it's a light background, and so the system bar content should be dark/black.Vilgot Fredenberg
01/30/2025, 12:23 PMdarkTheme
)
val view = LocalView.current
SideEffect {
val window = (view.context as Activity).window
val controller = WindowCompat.getInsetsController(window, view)
controller.isAppearanceLightStatusBars = !darkTheme
}
Bradleycorn
01/30/2025, 7:57 PMStylianos Gakis
01/30/2025, 8:32 PMBradleycorn
01/30/2025, 10:08 PMColton Idle
02/20/2025, 2:23 AMBradleycorn
02/20/2025, 2:13 PMMaterialTheme.ColorSheme
to set the status bar content color.
It uses a DisposableEffect (as suggested by @Stylianos Gakis) to set the color, and then in it's onDispose
, it "resets" the color back to whatever it was previously.
Here's what it looks like:
@Composable
fun ColorScheme.SetStatusBarContentColor(useDarkColor: Boolean) {
// When previewing in Android studio, the context is not an Activity.
// In that case, just return, since we can't access the window to set status bar colors.
val window = (LocalView.current.context as? Activity)?.window ?: return
val insetsController: WindowInsetsControllerCompat = WindowCompat.getInsetsController(window, window.decorView)
val initialValue by remember {
mutableStateOf(insetsController.isAppearanceLightStatusBars)
}
DisposableEffect(window) {
insetsController.isAppearanceLightStatusBars = useDarkColor
onDispose {
insetsController.isAppearanceLightStatusBars = initialValue
}
}
}
Stylianos Gakis
02/20/2025, 2:18 PMStylianos Gakis
02/20/2025, 2:19 PMuseDarkColor
your effect won't re-run again, is that what you want? If you go in there, then switch to dark mode, and then exit the screen does it work as you'd expect it to?Bradleycorn
02/20/2025, 2:27 PMYou can probably remove the "mutableStateOf" wrapping the initial valueAh yes, you are correct.
Also if you change theyeah, that's good enough for me at least for now. I don't need to change "dynamically". I have ayour effect won't re-run again, is that what you want?useDarkColor
Screen
composable that wraps each of my screens (it does things like fire screen view events for my analytics tracking system, etc). I call it from there to set the status bar content color for that screen. But yeah this would need some adjustments if you needed the content color to change while the same screen/composable is in composition (say like when certain content scrolls or something).
If you go in there, then switch to dark mode, and then exit the screen does it work as you'd expect it to?yep. So far so good 🤞