4 December 2015 · About 9 minutes read

Android: Toggling Your App's Theme

I was recently asked how an app’s theme can be toggled by the user in Android. This is a nice feature that is often seen in reading apps.

I’ve always found Android’s approach to theming overwhelmingly complex, but with the Android 5 Lollipop release and Design Support Library, Google have made great progress in simplifying things.

Recent builds of Android Studio have also included an early Theme Editor which can be used to edit and preview your app’s themes and how it will affect various widgets.

In this tutorial, we’ll build a simple app with a switch that lets the user toggle between dark and light themes.

Theme Toggling Screenshot

The full source code for this tutorial is available at https://github.com/cblunt/blog-android-theme-toggler.

$ git clone git@github.com:cblunt/blog-android-theme-toggler.git

Create the project

Note: For this project, I’m using the latest Android Studio 2.0 beta release (preview2).

We’ll start by creating a new application:

  • Create a new project called ThemeToggler targetting API Level 15 (Ice Cream Sandwich). We’ll use the Android Design Support library to support older devices running Android 4.

  • Choose Blank Activity to create a basic Activity with a Floating Action button.

  • Accept the defaults for the remaining screens to create your new application.

Build the UI

Once generated, we’ll add a switch widget for the user to toggle the app’s theme:

  • Delete the Hello World label from the default layout that was created.
  • Add a new Switch widget to the layout with the following attributes:
<!-- res/layout/content_main.xml -->
<Switch
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="Toggle Theme"
  android:id="@+id/switch1"
  android:layout_alignParentTop="true"
  android:layout_alignParentLeft="true"
  android:layout_alignParentStart="true"
  android:layout_alignParentRight="true"
  android:layout_alignParentEnd="true" />

Next, we’ll hook up our switch to toggle the application’s theme:

  • Add an OnCheckedChangeListener to the Switch in your Activity. The state of the Switch will be used to determine which theme is used:
// app/src/main/java/com/example/themetoggler/MainActivity.java
public class MainActivity extends AppCompatActivity {
  // ...
  protected void onCreate(Bundle savedInstanceState) {
    // ...
    Switch toggle = (Switch) findViewById(R.id.switch1);

    toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(CompoundButton view, boolean isChecked) {
        toggleTheme(isChecked);
      }
    });
  }

Saving the User’s Choice

When the theme is toggled, we’ll need to restart the current Activity to use the chosen theme. This is similar to configuration changes in Android (e.g. screen rotation) where the system will destroy and recreate the current Activity.

We’ll also need to store the user’s chosen theme so the re-created Activity knows which theme to use. It makes sense to store this in the app’s SharedPreferences so that the user’s choice is persisted across application launches.

After storing the user’s preference, we store a reference to the Activity’s original Intent, finish the current activity and restart it using that original Intent:

  • Add a new method, toggleTheme() to MainActivity to store the user’s preference and restart the current Activity:
// app/src/main/java/com/example/themetoggler/MainActivity.java
public class MainActivity extends AppCompatActivity {
  private static final String PREFS_NAME = "prefs";
  private static final String PREF_DARK_THEME = "dark_theme";

  // ...

  private void toggleTheme(boolean darkTheme) {
    SharedPreferences.Editor editor = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();
    editor.putBoolean(PREF_DARK_THEME, darkTheme);
    editor.apply();

    Intent intent = getIntent();
    finish();

    startActivity(intent);
  }
}

Creating the Theme

Finally, we’ll need to change the Activity’s onCreate method to use the user’s preferred theme.

However, we haven’t created any alternative themes yet, so let’s do that first.

Let’s add an alternative AppTheme.Dark which extends the default Theme.AppCompat. We can use the original AppTheme that Android Studio created as the basis for our theme:

  • Create AppTheme.Dark in styles.xml:
<!-- app/src/main/res/values/styles.xml -->
<style name="AppTheme.Dark" parent="Theme.AppCompat">
  <!-- Dark theme base colours -->
  <item name="colorPrimary">@color/darkColorPrimary</item>
  <item name="colorPrimaryDark">@color/darkColorPrimaryDark</item>
  <item name="colorAccent">@color/darkColorAccent</item>
</style>
  • We’ll also need to override some of the system themes, such as the NoActionBar theme. Use the existing AppTheme. styles as a base:
<!-- app/src/main/res/values/styles.xml -->
<style name="AppTheme.Dark.NoActionBar">
  <item name="windowActionBar">false</item>
  <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.Dark.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.Dark.PopupOverlay" parent="ThemeOverlay.AppCompat" />
  • I’ve also used declared colours in the theme. Put these in your colors.xml resource file:
<!-- app/src/main/res/values/colors.xml -->
<color name="darkColorPrimary">#1e2756</color>
<color name="darkColorPrimaryDark">#141831</color>
<color name="darkColorAccent">#2aac4b</color>

We’ve now declared enough for our themes to be used in the app. You can use Android Studio’s experimental Theme Editor to preview and tweak your themes:

  • Choose Tools->Android->Theme Editor
  • In the Theme dropdown, choose your AppTheme and AppTheme.Dark themes to preview how different widgets will look:

Theme Editor Preview

Applying the theme

Finally, back in our code, we can instruct our Activity to use the selected theme in onCreate().

Note that the code must be at the top of onCreate() (before the call to super.onCreate()) so that the app’s default theme (specified in AndroidManifest.xml) is overridden

// app/src/main/java/com/example/themetoggler/MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
  // Use the chosen theme
  SharedPreferences preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
  boolean useDarkTheme = preferences.getBoolean(PREF_DARK_THEME, false);

  if(useDarkTheme) {
    setTheme(R.style.AppTheme_Dark_NoActionBar);
  }

  super.onCreate(savedInstanceState);
  // ...
  • Also in onCreate(), we’ll update the switch to reflect the current choice (make sure this line goes before you add the onCheckedChangedListener to prevent an infinite loop:
// app/src/main/java/com/example/themetoggler/MainActivity.java
Switch toggle = (Switch) findViewById(R.id.switch1);
toggle.setChecked(useDarkTheme);
toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// ...

Finally, run your app and tap the switch to toggle between your dark and light themes. With every toggle, the Activity will be restarted.


This tutorial introduces how you can give the user a choice of theme for your app. The code you added for applying theme (at the top of onCreate()) would be common across all the Activities in your app.

For this reason, it would be a good thing to extract into a BaseActivity from which all your app’s Activities inherit.

I hope you’ve found this tutorial useful. Please let me know your thoughts and feedback in the comments below, or by getting in touch on Twitter (@cblunt).

Full Source Code: https://github.com/cblunt/blog-android-theme-toggler

Chris Blunt
Chris Blunt @cblunt
Chris is the founder of Plymouth Software. As well as code and business, he enjoys being a Dad, swimming, and the fine art of drinking tea.