Android’s Dark Mode through user configurations

Luciano Luzzi
The Startup
Published in
3 min readMay 16, 2020

Android 10 released Dark Mode, and with it, a ton of requests on Play Store.

exit, light, enter, night… mode!

Let’s check out an easy way to provide users with the option of selecting between dark mode, light mode, or following the system night mode.

The result that we want

We will need new preferences and material libraries:

Then we will make our app theme extend Theme.MaterialComponents.DayNight:

Extending Theme.AppCompat.DayNight is also possible.

For our settings fragment, we will use a preference resource file with ListPreferences to provide theme selection.

It is not a regular layout file, it needs to be placed inside the XML directory, inside of res.

The preference layout file:

Pay attention to entries and entryValues attributes: they will be used as a key-value pair.

The entries will be used to display a list, and the entryValues will hold the respective value for each entry, so make sure the indexes match.

Since we are going to use the values defined at themes_res.xml to save selected theme to sharedPreferences, let’s create a ThemeProvider class, whose’s scope is getting these values and return theme-specific values accordingly:

The getTheme method returns one of the following values:

  • MODE_NIGHT_YES — in other words, Dark Mode
  • MODE_NIGHT_NO — Light Mode
  • MODE_NIGHT_FOLLOW_SYSTEM — the app will follow the system dark mode

Method getThemeDescriptionForPreference will return a description for each theme, which we will use in our SettingsFragment.

Next, let’s create a settings fragment:

Looking at our preference listener, that’s where we get the user selected value, the ThemeProvider finds out which theme is represented by the selected string, and finally, we set the theme night mode.

The static method AppCompatDelegate.setDefaultNightMode will apply at run-time the selected theme to your application, but beware, it will recreate any already started activity — assert you holding data in lifecycle-aware components.

Preferences give us the option to set a summary provider for each preference.

The summary provider will update a preference summary accordingly to it’s selected value.

At this point, the functionality is already up and running: the theme is applied as soon as the user selects one of the options.

But when restarting the app, we will see that it is launched with the default light theme again, even though user selection is persisted.

Dealing with this is easy, for this example, we will apply the selected theme on each Application creation:

--

--