Material You (Dynamic/Adaptive) Colors in Legacy Android Apps
Context
So recently I decided to create a much needed update to one of my apps that I’ve left neglected, with the last update being deployed over a decade ago in 2013. This was one of my first coding projects so it was fun to revisit it, while feeling good to actually provide some maintenance for its thousands of loyal remaining users. Time had not been kind to the app, with it asking for notification preferences & full-screen mode despite those not ever being needed, as modern Android had a tricky time understand the app’s requirements.
As part of this update, I thought I’d refresh the design, moving to a new “Material You” kind of look, which allows the app to be themed dynamically based upon user preference (and often things like wallpaper colors).
Unfortunately implementing this kind of design in my app wasn’t so straightforward. What made this difficult is that I was working down to API (Supported Android versions) levels below that where this dynamic color system was introduced (I was working down to API level 24, or Android 7 Nougat). Additionally my app, being a decade old, is a “legacy” Java application, not a fancy Kotlin, Flutter or “Jetpack Compose” app. The documentation for things like colors are not only split across design theory and technical implementation, but now also across these different app build styles, which makes finding specific guidance quite a bit trickier than I remember from my early developer days. I could find bits & pieces, but I wasn’t able to connect it up for actual working code.
It likely I’ve since lost a lot of context/understand to transform the more general documentation to code. Looking back at some of the documentation, it’s now a fair bit more obvious.
Eventually though I figured how to use dynamic colors in a pleasant way, for my old Java-based app, with easy fall-backs for old Android versions:
Implementation
Here’s what I did:
First up is to follow the “Getting Started” page here to use Material Components for Android.
I then used the Material Theme Builder to create & generate out a base theme. You have to use the “Custom” tab to be able to export. I exported as “Android Views (XML)” This export included two files:
- This colors.xml file which I added to a
values
resource folder. - A
styles.xml
file from which I copied the<item>
s into the base theme of my ownstyles.xml
file as can be seen here.
Note, I am extending a Material 3 theme which can be seen here. This may be required/important for this kind of setup, I’m not sure.
I then added this to the onCreate
methods of my activities:
DynamicColors.applyToActivityIfAvailable(this);
With that done, default widgets (styled from the material theme I’m extending) will now use dynamic colors!
To specifically apply colors manually in layouts/styles, you can reference these via an ?attr/<name>
value,
with the names aligning with the items added to you styles.xml
file. Here’s an example of a background
and text color:
<Button
android:backgroundTint="?attr/colorTertiaryContainer"
android:textColor="?attr/colorOnTertiaryContainer" />
The names align with the color roles defined as part of the Material design documentation. If it helps to have a reference, the app I applied this to can be found open source here. I figured out some of this color-specific code stuff from the Material Components Android Color Section