Refactoring Android Themes with Style: structure and naming

Tram Ho

An ideal theme structure

We have a dark theme, a light theme, as well as a light theme with a dark toolbar.

It turns out that we have more than three topics – we have 22 topics and the topic hierarchy looks like this. Each square represents a topic, in which the arrows show how the topics inherit each other, but when we examine the usage, it’s not clear why a screen is used. one particular variation versus another and some use them all:

This application is growing rapidly. At the last count, we had about 130 activities and 300 fragments, developed by 18 Android engineers, spread across multiple teams releasing a new release, every week, so we could understand how We come to this position.

The hardest thing is we have two trees. This means it is easy to add a topic related error to a tree rather than another tree, and the same thing happens with error correction.

What we want is something closer to the structure presented:

There is a single tree with four layers:

  • app theme
  • base theme
  • platform theme
  • framework theme

App theme

At the bottom are the application topics we apply at the activity level:

  • Theme.Monzo.Light
  • Theme.Monzo.Dark

The main application theme will contain values ​​for color attributes, like colorPrimary , colorSurface and android:colorBackground . For example, android:colorBackground is defined as navy in Theme.Monzo.Dark but it is off-white in Theme.Monzo.Light .

When all views and layouts only reference color properties from our themes, adding the “night-mode” mode to the application becomes trivial: we can override the application themes. Use this in the values-night resource directory with a different set of color values.

Base theme

Our base theme, Base.Theme.Monzo , is where we override or define default styles for views and text appearance properties.

This layer usually does not contain references to specific colors. Instead, the style resource used here will reference properties from the application themes.

Avoid using hardcoded colors in this layer, meaning everything common to all themes is possible here.

Platform theme

The platform theme layer allows us to calculate API specific properties. Using resource qualifiers, we can specify a different platform theme for different Android versions.

This works based on the following principles:

  • Base theme depends on Platform.Theme.Monzo
  • Platform.Theme.Monzo is defined in each resource group where we need version-specific attributes
  • Each version of Platform.Theme.Monzo depends on the theme resource specific to the version, e.g. Platform.V23.Theme.Monzo
  • Version-specific topic resources inherit from resources reserved for older versions, unless it starts minSdkVersion in that case, it will depend on the theme framework.

Framework theme

We have chosen Theme.MaterialComponents.Light.NoActionBar as the theme framework to inherit. The framework theme provides many reasonable default values ​​so that we cannot specify everything.

Renaming and pruning trees

With so many themes and styles, it’s hard to know where to start. Part of this difficulty is that it is unclear how to use the themes because it is not clear what style resources are the theme. We decided to apply a strict naming convention to help us navigate the current state of the application.

The first rule we agree is to take advantage of the dot notation if possible, preserving parent use explicitly only in two cases:

  • theme overlay declaration, where we don’t want to inherit any properties
  • Change the namespace when inheriting from a style from another family

This makes it really easy to see the origin of a topic by eliminating the indirect:

Ref: https://medium.com/monzo-bank/refactoring-android-themes-with-style-restructuring-themes-15230569e50

Share the news now

Source : Viblo