Android Design System and Theming: Colors
1. Introduction
This is a continuation of the Article Android Design System and Theming: Typography. In that article, I explained why having a Style System help us to have a cohesive and easy to develop UI in our apps. I used typography as a guide to explain the main concepts related to the Android Application Theming, the Android solution to have a Style System.
Material Design Documentation is being updated constantly. Some of the information here presented might be slightly different in new Material Design Library versions.
In this article, I will follow a similar structure, but now I will explain a much noticeable aspect of our apps: Colors.
- We will see first how to properly name colors
- Then we will see the most important theme attribute for color and how to apply them in our theme.
- After that, we will see how the widgets behave with the theme colors.
- Later on, we will apply different themes to our app and add custom theme attributes.
- And finally, we will see some extra points.
Companion App: You can read and follow this article in this Github project.
2. Color naming
First of all, we have to select our colors. As far as in Android Studio 4.0.1 (In 4.1 is fixed﹡) if you create a new project with the empty activity wizard, the colors file looks like this.
We should change it.
As it is recommended the colors should have literal names (describe the value not how it’s used). To help you with color naming you can use the Material colors style, use a tool like name-that-color, or a Plugin like this one.
I will use these.
Now that we have our colors we have to set them in our theme attributes.
You can learn about theme attributes in my previous post in the section Theme attributes in less than 100 words.
﹡In Android Studio 4.1, the new project wizard creates the colors with literal names.
3. Color theme attributes
An image is worth 1000 words.

Here we can see the 12 most important color attributes that the Material Design Library offers us.
When creating your Theme you don’t need to change all of them. Start changing only the Primary and Secondary and their cousins (
variant
andon
). The rest of the attributes will, most of the time, do the job.
As you can see the color attributes are divided into some colors like colorPrimary
, and in how should the foreground of that color be, like colorOnPrimary
.

This is very helpful because we have now one place where we define our colors and also how the foreground of that color is, so we can be confident that there won’t be visibility problems. Like if a dark-colored button has a dark-colored text.
There is an intrinsic relation between
primary
,variant
andon
. If you change one of them you should verify that everything keeps looking good between each other.
You can read more about common theme attributes in the Google Developers Blog Post from Nick Butcher Common Theme Attributes
4. Update your theme with your colors
Now that we have our colors set, let’s apply them to our Theme.
First of all and in Android Studio 4.0.1 (In 4.1 is fixed﹡) the Empty Activity
wizard creates this style:
We will clean this up.
First, make the parent inherit from a Material Design theme. I will use Theme.MaterialComponents.DayNight.DarkActionBar
Don’t forget to add the libray
com.google.android.material:material:<latest_version>
in your gradle module file.
Second, change the name to reflect that it is a theme.
In section 8.1. Use a Base Theme you can see a better approach when having a less simple themes hierarchy.
Finally, move it to a themes.xml
file.
﹡In Android Studio 4.1, the new project wizard, the theme is already created in the
themes.xml
file.
4.1 Naming Styles
Because there is no XML tag <theme>
we have to use the <style>
tag for themes and styles indistinctly. Therefore to not getting confused with our design system, we need a convention to name them.
For Themes and Widget Styles the convention is:
- Use
Theme.YourAppsName.ThemeVariantName
for the themes. - Use
Widget.YourAppsName.WidgetType.WidgetVariantName
for the widget. - Themes will be set for a
theme
in an XML. - Widgets will be set for a
style
in an XML.
With this, it is easy to see that we are not using themes when we should use styles, and vice versa.
4.2 Naming Files
- Add your themes in the
themes.xml
file - Add your widget styles in the
styles.xml
file
Now if we run our app we can see how the colors are applied as we defined them in the theme.
5. Widgets and default attributes.
One of the main advantages of using theming is how easy they work with widgets.
You might be tempted to create a style for the buttons with your attr/colorPrimary
and attr/colorOnPrimary
. You don't need that.
Android System and the MD Library will do all for you. This will be shown equally. The button content color is set to colorPrimary
and colorOnPrimary
for the text, so you don't have to do anything.
The Material Design website has all the information about theme attributes so is very easy to understand and modify how they work.
Here is an extract of the Container Attributes of the Contained button Component Docs

The Material Design Library specifies different styles for the different components.
For example, the Button
widget has 3 different styles. Contained, Text, and Outlined. These styles use theme-attributes to define their look and feel. We can just change our theme attributes and set the specific Material Design style to accomplish a robust Design System in our app.

Check how the Contained Buttons does not need any specification to be painted with the theme colors, and how the others just need to set the style to a Material Design Library Style.
Note how the Outlined Button Style is set by a theme attribute called materialButtonOutlinedStyle
. There is also a borderlessButtonStyle
attribute for the Text Button, but as of today, the official Material Docs shows the snippet above.
There are many other theme attributes defined in the MD library, and updates in the official documentation occur regularly. Is a good practice to review them while developing.
Android engineers recommend using Material Design Components. You can read more about it in this Android Developers post: We Recommend Material Design Components
There are a couple of places where this can be more complicated than it looks, but most of the time you won’t have problems.
Check the companion app to see how some widgets are painted just defining a theme and letting the Android and the default values do the rest.

5.1. Widget Customization
In case you need to customize a widget, start from the Base Material Widget, and create a specific style for it.
As mentioned before in 4.1 Naming Styles, name the styles with the Widget.
prefix as best practice.
5.2 Widget Customization with Widgets Theme Attributes
There are many built-in theme attributes related to Material Widgets, like buttonStyle
, appBarLayout
or bottomNavigationStyle
.
You can set these theme attributes in your theme to a specific style, and forget about setting the style in the view.
With this technic, we avoid adding styles directly in the view and reduce the risk of adding a wrong one.
6. I need more Themes
Your app might have different versions like Free and Premium and you want to have different looks between both. Another scenario is that your application uses different color schemes on different screens. In these cases, you can have more than one theme.
Because your application has the theme set up in the manifest, to select a different one in an activity or fragment you will need to do it programmatically.
For an activity is as easy as calling setTheme(R.style.yourTheme)
before calling setContentView()
In a fragment, setting the theme programmatically is done like this:
Here you can find the official setTheme documentation
Note 1: If you need to change your theme after views are instantiated you will need to call
recreate()
to inflate the views again with the new theme.Note 2: Notice how the dots are replaced with underscores when accessing the theme from the resources.
Theme.MyApp.Alternative
in the themes.xml will beTheme_MyApp_Alternative
in your Activity or Fragment.
Check it in the companion app: ThemeAlternativeFragment.kt
6.1. Theme Overlays
There are times that you need to change the theme but only in a fraction of your view hierarchy. For that, there is the Themes Overlays technic. This topic was already covered in my previous post.
Here is an excerpt:
In any of your views, you can add the
android:theme
attribute and set it to a specific theme. The view and all its children will use the new theme. ThemeOverlays inherit from an empty parent, should define as few attributes as possible, and its name should start withThemeOverlay
, thus it's clear its purpose.
As you can see in the sample app I had to change the background in the layout android:background="?attr/colorSurface"
so it gets the proper surface color in the background. Also, I needed to change the text color in the style.
Depending on your necessities you will have to tweak little some attributes, but most of them will work properly.

6.2 Premade overlays
The Material Design Library provides some premade overlays. Like ThemeOverlay.MaterialComponents.Dark
Before you build your own, is good to check if some of them already comply with your requisites.
You can read more about theme overlays in the Google Developers Blog Post Android Styling: themes overlay
7. What if 12 attributes are not enough?
One of the powers of theming is the ability to change the whole UI styles easily. Imagine this scenario: your app has 2 themes for normal and premium users. The primary color is different for both, just creating a new theme with a different primary color and changing the theme for each of the user types will be sufficient.
Now imagine that our design team wants a specific FAB button color for the premium members, which is not the same as the premium secondary color. In this case and because FAB buttons use colorSecondary
attribute to tint it, we need a solution.
We can define a custom theme attribute that will be used to tint the fab buttons, instead of the default attribute (in this case colorSecondary
).

You can see in the images above how the EXTENDED FAB
is colored as a default Fab Button using the secondary color on both screens. But for the CUSTOM ATTRIBUTE
button, it used the secondary color (default behavior) in the base theme (left), but it uses the orangePremium
color, set in the theme attribute fabBackgroundColor
for the alternative theme(right).
8. Extra
8.1. Use a Base Theme
It is a good practice to have a Base Theme where you add things that won’t change for any theme, like text appearances, shapes, or widgets styles, and create specific themes inheriting from it.
8.2. Dark Theme
Dark Theme is a big topic that will fit best in a different post. But to give it a try in your app you can do these simple steps:
- First, create a file in
res/values-night
and call ittheme.xml
- Secondly, create a theme with the same name as your primary theme name (the one you set in the manifest). You can simply copy and paste it.
- Third, change the basic colors for the Dark Mode. To start, use the same ones you have in the light theme but with lower saturation.
- And finally, copy and paste this code to add a button to toggle the Dark Mode in your app.
The important part is the one inside the
setOnClickListener
The rest is to give a plug&play code snippet.
Now you can see your app in dark mode with the default values.
There is much more to talk about Dark Themes but this post is already big enough. Let’s do it in another one.
8.3. PrimarySurface
colorPrimarySurface
is a theme attribute (and a variant of some styles) that helps while working with surfaces in Dark Mode.
Several colored widget surfaces are set to the primary color. Like the Toolbar or Bottombar, but in case we change the theme to a Dark Theme, the primary color as the surface color does not look appropriate.
For these cases there are colorPrimarySurface
and colorPrimaryOnSurface
. Widgets can use these attributes as backgroundTints so in Light Theme the primary color will be used, but in Dark Themes a dark surface color will be selected.
We can see this behavior in the BottomBar style. In the companion app, the BottomBar style is Widget.MaterialComponents.BottomNavigationView.PrimarySurface
. When we turn on the Dark Mode the BottomBar will be colored as dark grey.
If we instead used Widget.MaterialComponents.BottomNavigationView.Colored
when the Dark Mode is turned on, the BottomBar will be colored as primary.

9. Recap
There are only 4 steps to have your app theme up and running.
- Add your primary and secondary colors to your
colors.xml
file. (Use literal names) - Create your theme in the
themes.xml
file and reference it in your manifest. - Reference the main color theme attributes (
primaryColor
,primaryVariantColor
,secondaryColor
... )to your preferred ones. - Use the Material Design Widgets in your layouts, and adapt them using
styles
in case you need specific customization.
10. Conclusions
Android Theming is a powerful technic that can help us to have a cohesive UI and speed up our development.
The topic is big, and there are many things to learn, but to have a base theme is straight forward and as you saw in the Recap section there are only 4 easy steps. (In Android Studio 4.1 the first 3 steps are already done in new projects)
If you haven’t yet, you can check my previous article Android Design System and Theming: Typography. And as I mentioned there, the general topics here presented can be applied also to text appearances and shapes.
Before saying goodbye I recommend you checking this Android Dev Summit talk Developing Themes with Style by Nick Butcher and Chris Banes. There are also several posts in Android Developers Medium by the Android Design Team covering all topics about theming and styling.
Finally, I hope this article helps you to understand Android Theming and Styling a bit better.
Thank you for reading.
Originally published at https://www.hugomatilla.com