Designing a Dark Theme on Android

Giovanni Piemontese
Smart Launcher Blog
5 min readJul 30, 2019

--

2019 is the year of dark theme for the apps. (Almost) Everybody loves the idea to have dark apps interfaces in their hand to reduce eyestrain and battery consumption.

In Smart Launcher we loved the idea of having a Dark theme too. But, if you are on Android and you use custom UI components for your app you may notice it’s not a very simple task, so we had to come up with a precise strategy.

I wrote this article to share an overview of the process we used in Smart Launcher from a design perspective, confident that this process could lead you to design dark themes more easily and more organized on Android. For this reason all the technical information won’t be analyzed in detail.

Design phase

The first thing to do is to design our components for the light and dark theme. To do it efficiently, we focused on the architecture of the user interface. We abstracted the interface reducing it to its core elements: surfaces and items. Analyzing the UI you can start noticing the relationship between some component behaviors (icons and texts with the same color, different surfaces that behave the same, etc.). Then, we named them according to these associations.

Material design already offers an important overview of how things work on Android. I would suggest avoiding to go too far from them, but it’s also good to adapt the guidelines to your actual needs.

You can finally duplicate the light UI and start defining the new component tints starting from the background, that is usually the darker element. Try to keep elevated surfaces readable playing with lighter colors or borders. Remember that shadows are barely visible with dark themes. Also, keep in mind that colors perform differently from light to dark surfaces, so tweak them to keep contrast and color readability high.

Once you are happy with the overall look of the dark theme and you are sure that you followed the accessibility guidelines, you can finally get down to the nitty-gritty.

Reorganization of the style sheet

Of course, this abstract UI represent just a part of all the components you usually use in your app, but it’s a good way to start. There are so many colors and component behaviors in the real product that we needed to clean up and improve the whole structure of UI components both on the design system and on the dev style sheet. I bet you need it too.

In Smart Launcher, I redefined our entire color palette, I named it coherently together with the devs so that there a no mismatching of styles. Do not be greedy, all these colors are the ones that will be used both on the light theme and the dark theme. They will be the fundament of the next important step: connecting colors and components behaviors with Android attributes.

<resources><color name="white32">#52FFFFFF</color>
<color name="white50">#80FFFFFF</color>
<color name="white70">#B3FFFFFF</color>
<color name="white90">#E6FFFFFF</color>
<color name="white">#FFFFFFFF</color>
...
<!--Zagare-->
<color name="zagareLight">#2288FF</color>
<color name="zagareDark">#0044EE</color>
<color name="zagare">#0066ff</color>
<color name="zagare_a70">#B30066ff</color>
<color name="zagare_a50">#800066ff</color>
<color name="zagare_a30">#4D0066ff</color>
...
<!--Full Colors-->
<color name="orange">#F67B12</color>
<color name="orange_a30">#4DF67B12</color>
<color name="orangeLight">#FFCA9D</color>
<color name="orangeDark">#B75400</color>
...
<!--and soooo many more--></resources>

Giving Attributes to the UI components

To make things clear for the entire team, we all made a cognitive shift.

The UI components tint is not defined by a unique color anymore, but it is defined by an attribute.

Indeed, the attribute controls which color to set for a surface or an item when it is used in a specific theme: light theme, dark theme (or many others). For example, Card surfaces have not anymore an absolute value as #FFFFFF (or a resource as White100) as a tint, but it has a relative attribute called colorCard. This attribute tells Android to tint the Card as White100 on Light theme and DarkGrey800 on Dark Theme.

Following this philosophy, I prepared some papers on our design system, Acrylic Design, to define (and remember) each attribute name and its color behavior with the different themes. I assume this is useful both for solo-designers, for a design team and a dev team.

All you need to do now is to transform the specs into working code. You start by declaring the attributes according to the ones you defined in the previous phase.

<attr name="colorBackground" format="reference" />
<attr name="colorCard" format="reference" />
<attr name="colorCardEdge" format="reference" />
<attr name="colorSurface" format="reference" />

Then, you define for each theme how the attributes should behave by giving them the right color from the palette made during the reorganization of the style sheet.

<style name="AcrylicTheme.Light">
<item name="colorBackground">@color/darkGray_900</item>
<item name="colorCard">@color/darkGray_800</item>
<item name="colorCardEdge">@color/transparent</item>
<item name="colorSurface">@color/darkGray_800</item>
...
</style>
<style name="AcrylicTheme.Dark">
<item name="colorBackground">@color/white100</item>
<item name="colorCard">@color/white100</item>
<item name="colorCardEdge">@color/transparent</item>
<item name="colorSurface">@color/white100</item>
...
</style>

You can now use the attributes with the items on your UI.

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"/>

The result and final thoughts

When we started looking at the result, we could not believe how seamlessly it worked. The system is so organized and flexible that the benefits fall also on the design of the product. Right now, when we design new components we think in advance how each item matches with a defined color behavior. A new surface will automatically adapt its tint on the different themes. Thanks to that, the UI will gain consistency and adaptability.

Once you build the structure behind, it requires almost no effort to build new themes. Lately, we added an AMOLED theme that presents a full black UI, specifically designed to AMOLED displays. All we did was to copy-paste the Dark theme values and change theme substituting the connected colors with new ones from our palette.

If you have some more solutions to share, please respond to this article. We are happy to hear from you!

Thank you for reading.

--

--