Implementing Dark Theme in Android

implementing-dark-theme-in-android-0

In today’s connected world, millions of different applications are competing for the attention of users with new and innovative features every day. One of the crazy popular features in the last couple of years has definitely been Dark theme.

More than meets the eye

Besides its sophisticated looks, dark theme offers much more. One of the biggest benefits is power reduction. When running in dark, you light up less pixels and the result is significant power usage reduction – up to 60 percent. It also makes your app easier to use in low-light environments and helps people sensitive to bright light get a better user experience.

Last year, Google introduced a new feature on Android 10 called System theme change. It enables switching between the light and dark theme in the system but also affects all apps which support the dark theme. That’s why developers are highly encouraged to start implementing dark theme in their apps.

Easy dark mode with Force dark

With Android 10 came one more interesting feature called Force dark. It’s convenient for developers who don’t want to invest a lot of time into dark theme implementation. If you enable Force dark by setting android:forceDarkAllowed=”true” in your activity’s theme, it will analyze the views in runtime and automatically convert them to dark before they are drawn on the screen.

	
	
<style name=”Theme.AppCompat” parent=”Theme.AppCompat.Light”>
    ...
<item name=”android:forceDarkAllowed”>true</item>
    ...
</style>

In most cases, if layouts are not too complicated, it does a solid job.

Light version
Dark version

That being said, some slightly more complicated layouts can end up looking funny, so make sure to test your app well before settling with Force dark.

Light version
Dark version

Another disadvantage of this approach is the lack of control over the app’s appearance in the dark version. That’s why custom implementation is highly recommended.

Laying the groundwork is half the success

Before digging in the dark theme implementation you need to ensure using themes and styles when defining your layouts. Removing all hard coded colors or direct referencing to color resources out of your app and instead using theme attributes will make the process of dark theme implementation faster and much easier.

The biggest challenge is adjusting your custom views. This article describes well how to achieve this without much difficulty. Once you’ve done spring cleaning, you are ready for implementation.

Custom dark theme implementation

First step is to make your app’s theme inherit one of the DayNight variants:

	
	
<style name=”AppTheme” parent=”Theme.AppCompat.DayNight”>

Or if you prefer MaterialComponents theming (recommended option):

	
	
<style name=”AppTheme” parent=”Theme.MaterialComponents.DayNight”>

What really happens then is it enables the -night resource qualifier when in dark theme.

values/themes.xml

	
	
<style name=”Theme.AppCompat.DayNight” parent=”Theme.AppCompat.Light”>

values-night/themes.xml

	
	
<style name=”Theme.AppCompat.DayNight” parent=”Theme.AppCompat”>

First theme is being used when your app is running in Light mode and the second one in the Dark mode. That’s how you need to define your light and dark variants of BaseApp theme.

Once you have properly defined all attributes in your theme that are relevant for defining your App’s looks, all you have to do is modify those values in the dark version of your theme. You can define all required values in night variant of resources such as drawables-night, styles-night, colors-night etc.

Change themes in app

The idea for theme changing is to let the users choose. There are 4 recommended theme options and compatible AppCompat.DayNight modes:

  • Light – MODE_NIGHT_NO
  • Dark – MODE_NIGHT_YES
  • Set by Battery Saver (for Android 9 and earlier) – MODE_NIGHT_AUTO_BATTERY
  • Set by System default (for Android 10) – MODE_NIGHT_FOLLOW_SYSTEM

The last two are recommended options depending on the Android version of your App. To switch between day and night theme call AppCompatDelegate.setDefaultNightMode(int mode) with one of the modes.

Starting with AppCompat v1.1.0, calling this method automatically recreates all started activities and you can see instant theme change. The only problem is that change is not persisted once the process is dead. You have to remember and retrieve user selection and call the appropriate method every time your app process is started.

Let there be dark or light – it’s up to you

Even though DayNight has been available for a while now, the improvement over the course of the last year has been the most significant, the result of which is an uncomplicated procedure of dark theming which will, once implemented, enrich any app with an attractive and useful feature that will light your users’ day up.