One Off the Slack: How Do We Implement Theme Overlays in Compose UI?
I have an app that uses a Material theme in light and dark variants … pretty standard stuff. The light theme uses a white surface color and a pretty dark (navy blue) primary color. So far so good…
However, we have a few screens (formerly fragments) where the design calls for the color scheme to be inverted. That is, the dark (navy blue) color is used for the background (surface) and the content (text, textfields, etc) is white. I’m wondering what is the best way to deal with this? At first, I created a
DarkSurfacecomposable that wraps a surface and sets up some CompositionLocals to handle the color inversions. But the more I go down that path, the more cumbersome and wrong it seems. Now I’m wondering if I should create a new theme for these screens to use. Anyone else ran into something like this before and have any ideas on how to handle it?
In the classic
View system, we might try accomplishing this via a theme
overlay, but that’s not really a thing in Compose UI.
Google’s Nick Butcher points out the alternative: nested themes:
You can nest themes. See this sample which has a Pink theme at the root of the screen:
… but But then sets a Blue theme for a section of the UI
(note: in preparing this post, I swapped the original
master links that Nick used with
ones tied to the
BlueTheme() are defined as top-level functions in
of the Owl sample project, and they are just wrappers around
OwlTheme(), in turn, wraps a
MaterialTheme() but also overrides the
LocalImages composition locals. But the colors from
are just passed into
MaterialTheme() sets up the design system for
the composables it wraps, and you can nest
MaterialTheme() calls to replace the design
system for particular screens, portions of screens, etc.
Bradleycorn agreed with the plan:
Yep, that’s the path I’m going down now, thanks for the examples. It seems much more “correct” than creating a bunch of CompositionLocals and a wrapper composable to set them to provide colors. That got to be a mess fast.