Illustration by Virginia Poltrack

Android styling: themes vs styles

Nick Butcher
Feb 4, 2020 · 6 min read

The Android styling system offers a powerful way to specify your app’s visual design, but it can be easy to misuse. Proper use of it can make themes and styles easier to maintain, make branding updates less scary and make it straightforward to support dark modes. This is the first in a series of articles where Chris Banes and I will set out to demystify Android styling so that you can make stylish apps without pulling your hair out.

In this first article, I’ll take a look at the building blocks of the styling system: themes and styles.

Theme != Style

Both themes and styles use the same syntax but serve very different purposes. You can think of both as key-value stores where the keys are attributes and the values are resources. Let’s take a look at each.

What’s in a style?

A style is a collection of view attribute values. You can think of a style as a . That is the keys are all view attributes i.e. attributes that a widget declares and you might set in a layout file. Styles are specific to a single type of widget because different widgets support different sets of attributes:

Styles are a collection of view attributes; specific to a single type of widget

As you can see, each of the keys in the style are things you could set in a layout:

Extracting them to a style makes it easy to reuse across multiple views and maintain.

Usage

Styles are used by individual views from a layout:

Views can only apply a single style — contrast this to other styling systems such as css on the web where components can set multiple css classes.

Scope

A style applied to a view only applies to that view, not to any of its children. For example, if you have a with three buttons, setting the style on the will not apply that style to the buttons. The values provided by the style are combined with those set directly in the layout (resolved using the styling precedence order).

What’s a theme?

A theme is a collection of named resources which can be referenced later by styles, layouts etc. They provide semantic names to Android resources so you can refer to them later e.g. is a semantic name for a given color:

These named resources are known as theme attributes, so a theme is . Theme attributes are different from view attributes because they’re not properties specific to an individual view type but semantically named pointers to values which are applicable more broadly in an app. A theme provides concrete values for these named resources. In the example above the attribute specifies that the primary color for this theme is teal. By abstracting the resource with a theme, we can provide different concrete values (such as =orange) in different themes.

Themes are a collection of named resources, useful broadly across an app

A theme is similar to an interface. Programming to an interface allows you to decouple the public contract from the implementation allowing you to provide different implementations. Themes play a similar role; by writing our layouts and styles against theme attributes, we can use them under different themes, providing different concrete resources.

Roughly equivalent pseudo-code:

Which allows you to vary the way that is rendered, without having to create variants of it:

Usage

You can specify a theme on components which have (or are) a e.g. or /s:

You can also set a theme in code by wrapping an existing with a which you could then use to inflate a layout etc.

The power of themes really comes from how you use them; you can build more flexible widgets by referencing theme attributes. Different themes provide concrete values at a later time. For example, you might wish to set a background color on a section of your view hierarchy:

Rather than setting a static color ( or a resource) we can delegate to the theme by using the syntax. This syntax means: query the theme for the value of this semantic attribute. This level of indirection allows us to provide different behavior (e.g. providing a different background color in light and dark themes) without having to create multiple layouts or styles which are mostly identical but for a few color variations. It isolates the elements that are changing within the theme.

Use the syntax to query the theme for the value of this semantic attribute

Scope

A is accessed as a property of a and can be obtained from any object which is or has a e.g. , or . These objects exist in a tree, where an contains s which contain s etc. Specifying a theme at any level of this tree cascades to descendent nodes e.g. setting a theme on a applies to all the s within it (in contrast to styles which only apply to a single view).

This can be extremely useful, say if you want a dark themed section of an otherwise light screen. Read more about this behavior here.

Note that this behavior only applies at layout inflation time. While offers a method, or offers an method, these need to be called before inflation. Setting a new theme or applying a style after inflation will not update existing views.

Separate Concerns

Understanding the different responsibilities and the interaction of styles and themes, helps to keep your styling resources more manageable.

For example, say you have a blue theme for your app, but some Pro screens get a fancy purple look and you want to provide dark themes with tweaked colors. If you tried to achieve this using only styles, you would have to create 4 styles for the permutations of Pro/non-Pro and light/dark. As styles are specific to a type of view (, etc) you’d need to create these permutations for each view type in your app.

Exploding permutations of widgets/styles without theming

If instead we use styles and themes we can isolate the parts which alter by theme as theme attributes so we only need to define a single style per view type. For the above example we might define 4 themes which each provide different values for the theme attribute, which these styles then refer to and automatically reflect the correct value from the theme.

This approach might seem more complicated as you need to consider the interaction of styles and themes, but it has the benefit of isolating the parts that change per theme. So if your app rebrands from blue to orange, you only need to change this in a single place, not scattered throughout your styling. It also helps fight a proliferation of styles. Ideally you only have a small number of styles per view type. If you don’t take advantage of theming, it’s easy for your file to get out of hand and explode with different variations of similar styles, which becomes a maintenance headache.

Join us in the next article where we explore some common theme attributes and how to create your own:

Android Developers

The official Android Developers publication on Medium

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store