At Google I/O 2019 arguably one of the biggest cheers was for Dark Theme, a systemwide setting on your phone which changes all apps which support it to a darker style. There are many reasons a user might want to do this – to save battery, to make your app easier to use in low light – it also looks pretty darn cool.
Luckily for us at Moneybox, around this time we were just about to go through a large re-design of the app, which gave us the perfect opportunity to embed dark mode into our design. Keep reading to find out how we implemented Dark theme in our Android app.
Before our redesign we wanted a quick win which would make our screens dark mode compatible with very little work. This is where “force dark” comes in handy. It allows Android to take over and invert the colours on the screen. You can achieve this by setting force dark in your activities/components style:
You can set this for entire activities or individual components, it can also be set directly in code.
Implementing a Custom Theme
Force dark allows you to quickly support Dark theme in your application, but it doesn’t allow you to express your brand’s individuality. That’s why we wanted to implement our custom solution as early as possible.
To implement a custom solution the app’s theme must inherit from a DayNight theme. Dark theme works by defining a colour for a particular component both in Light theme and Dark theme. This means when you switch from Light to Dark mode it renders the screen differently with the specified colour for Dark theme. You specify all the colours for Light theme in res/values/colors.xml file and all the colours for Dark theme in res/values-night/colors.xml.
Custom colour scheme
Implementing a Dark theme is fairly straightforward. The difficult part is defining rules so your app looks consistent throughout and your design team doesn’t double their work. At the start of our redesign project our UX team helpfully devised a set of global rules to define what colours certain components were in Light and Dark mode:
This allows us to refer to our component colours in xml e.g. @color/background_primary, as opposed to a standard colour such as @color/white which only works in Light mode. You can still use real colours in xml but only if you want that component to be the same colour in both modes. Below is a screen from our house buying calculator, a tool designed to help our customers save for their first home:
In this screen we use a number of different colours to render this page:
- @color/background_primary – White in Light mode and our custom background in Dark mode.
- @color/text_primary – Teal in Light mode and white in Dark mode.
- @color/aqua – The same in both Light and Dark mode.
- @color/teal_10_transparent – Teal with 10% transparency. This is the same colour in both Light and Dark mode, however it looks different as the background behind bleeds through.
Images can also be changed in different lights. You can specify completely different images for Dark theme in res/drawables-night. However, a better way suggested by Google is to use the same image but Dark theme enabled colours to draw the vector image. In our Payday boost screen we use a transparent colour in the circular background of the image, and use a different colour altogether for the clouds to make them more subtle. The path below draws a cloud in both white and teal.
Our blog is implemented using a web page so it’s available both in the app and on our website. It’s also Dark theme enabled using dark styling in CSS, which means we can keep our custom Dark theme in our web pages. This can be enabled in your web view by adding the following code:
This will render your custom CSS if you have implemented it, but allow force dark to work its magic if not.
And that’s it – how we redesigned our entire app to have a custom Dark theme and embed it into our future designs. In most cases, with our structured style guide we only need to design in Light mode, then use our rules to build our dark screen. When we launched our rebranded app Dark theme was a much loved new feature, which makes the work it took to implement it all worth it!
By Jaeren Coathup, Lead Android Developer