Themes & Styles in Android
An important part of designing user interfaces in the Android framework is to use themes and styles as much as we can to separate design logic and behaviors into a single manageable place.

First, let’s start with the differences between themes and styles. Why they are called the way they are?
Styles
A style is a set of attributes of an individual view. It is declared in res/values
, usually named styles.xml
, but you can change it to whatever you want.
Most of the predefined style names usually start with Widgets.
For example, styles in MaterialComponents are in Widget.MaterialComponents.
To apply the style to all buttons in our app, we need to use a theme which we will talk about it in a second.
After setting style in AppTheme
, we will see all of our buttons in the app changed to be outlined. Any view which is inflated inside AppTheme
will have the style — Widget.MyApp.Button.OutlinedButton
Style Inheritance
One of the cool things about styles is the ability to inherit from any style. As you can see in the example above, there is a parent
keyword which we used to specify where to inherit from. There are two types of style inheritance. Explicit and Implicit are the same, it’s just different in syntax.
- Explicit inheritance — specify
parent
keyword.
- Implicit Inheritance — Using dot notions.
Both methods are handy in different cases.
- Mixed Inheritance (Unofficial)— A combination of implicit and explicit
Question: Which one does YourStyle
inherits from?
Answer:
If parent
keyword is specified, the implicit inheritance will be ignored, so YourStyle
inherits from HerStyle
.
In MaterialComponents, they use this technique to classify themes, text appearances and styles into different Base style’s names such as Base
Widget
Theme
TextAppearance
ThemeOverlay
and more.
It’s a best practice to put your style there since it will give save your time to try to distinguish which one is which.
By convention,
<StyleType>.<YourAppName>.<Widget>.<Behavior>.<Inherited Behavior>
…. So on and so on
For example,
Assume that my app’s name “Medium”, so to define a custom style for a text view, we should name it as:
Widget.Medium.TextView
Widget.Medium.TextView.StylishTextView
Widget.Medium.TextView.StylishTextView.InvertedStylishTextView
If it is a button
Widget.Medium.Button
Widget.Medium.Button.UnelevatedButton
Widget.Medium.Button.UnelevatedButton.CutCornerButton
also, if it’s a text appearance it should be
TextAppearance.Medium.TextAppearanceBody
TextAppearance.Medium.TextAppearanceHeading1
TextAppearance.Medium.TextAppearanceDisplay2
Finally, ShapeAppearance. You might be asking yourself, what the heck is it? Well, shape appearances are similar to text appearances, but it’s for the shape of an individual view rather than text format.

To achieve this shape, we have to declare a shape appearance for it. Read more detail about Shape Appearance here.
Themes
A theme is used to style the view hierarchy. When you apply a theme to a view, it will then apply those to all its children. On the other hand, a style is just for a single view. Themes can be used to change the value of the attributes to be the different values we prefer. For example, if we want to change our app accent color for our entire activities, we will definitely use a theme to achieve that. I am pretty sure that you’re familiar with that!
As you can see in the example above, we use a theme to change theme attribute and property values. Not only colors, but we can also change almost everything including font family, text appearances, button styles, text styles, and more.
Theme Attributes
Changing some values of our app globally would be a pain if we didn’t have Theme Attributes. By defining an attribute that we can refer to later in the app or XML is necessary as changing an attribute in the theme will affect your whole app, which is cool isn’t it? That’s why Chris Banes and Nick Butcher encourage us to always use theme attributes whenever possible.
Here is a list of some useful theme attributes I knew and have been used for awhile
Color Attributes
- ?attr/colorPrimary
- ?attr/colorPrimaryVariant
- ?attr/colorSecondary
- ?attr/colorSecondaryVariant
- ?attr/colorOnPrimary
- ?attr/colorOnSecondary
- ?attr/colorOnSurface
- ?attr/colorSurface
- ?android:attr/texColorPrimary
- ?android:attr/textColorSecondary
- ?attr/colorControlNormal
- ?attr/colorControlActivated
- ?attr/colorControlHighlight
Style Attributes
- ?attr/appBarLayoutStyle
- ?attr/materialButtonStyle
- ?attr/materialButtonOutlinedStyle
- ?attr/toolbarStyle
- ?attr/navigationViewStyle
- ?attr/recyclerViewStyle
- ?attr/coordinatorLayoutStyle
- ?attr/checkboxStyle
- ?attr/materialCardViewStyle
There are a lof style attribtues I couldn’t list it all there. I hope you get the point!
Text Appearance Attributes
- ?attr/textAppearanceButton
- ?attr/textAppearanceBody1
- ?attr/textAppearanceBody2
- ?attr/textAppearanceHeadline1
- ?attr/textAppearanceHeadline2
- ?attr/textAppearanceHeadline3
- ?attr/textAppearanceHeadline4
- ?attr/textAppearanceHeadline5
- ?attr/textAppearanceHeadline6
- ?attr/textAppearanceSubtitle1
- ?attr/textAppearanceSubtitle2
- ?attr/textAppearanceOverline
- ?attr/textAppearanceCaption
- ?attr/textAppearanceListItem
- ?attr/textAppearanceListItemSmall
- ?attr/textAppearanceListItemSecondary
Shape Appearance Attributes
- ?attr/shapeAppearanceLargeComponent
- ?attr/shapeAppearanceMediumComponent
- ?attr/shapeAppearanceSmallComponent
Dimens Attributes
- ?attr/actionBarSize
- ?android:attr/disabledAlpha
- ?attr/dialogCornerRadius
See more in this article by @crafty
Theme Attributes and Dark Mode
Light and dark mode are now becoming the importance of every mobile app, so in order to address that we have to design our app carefully. If your app is not created with theme attributes in mind I will be a pain to migrate from light to dark and vice-versa.
⚠️ Avoid using hardcoded values
You might be thinking using @color/colorPrimary is a good option but it’s not even though it is better than using a plain hardcoded text. The best option is to use a theme attribute over @colors/my_color_name.️