Pier Pier - 2 months ago 12x
Android Question

How to update my project creating a multi theme app

I'd like to make a

to let the user personalize the appearence of the app.
In this activity the user can choose to keep the app in a "light theme" (that means for example white backgrounds with black texts) or a "dark theme", the opposite colours of light theme to favour the night use.

How could it be done?

I was thinking about creating different layouts in xml for each theme.


The images below are examples of
, I'd like to change the appearence for the whole app, not single activity.

enter image description here

enter image description here

enter image description here

enter image description here


This is how I've done it for my app. I'm sure my approach can help.

Set up your Light and Dark themes in styles.xml like this:

     <!-- Use this theme in Manifest by default -->
    <style name="MyLightTheme" parent="Base.AppTheme.Light"></style>
    <!-- Base light theme containing all styles -->
    <style name="Base.AppTheme.Light" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        ... Other styles

    <!-- Use this to switch to Dark theme -->
    <style name="MyDarkTheme" parent="Base.AppTheme.Dark"></style>

    <!-- Base dark theme containing all styles -->
    <style name="Base.AppTheme.Dark" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        ... Other styles

Since you're controlling Theme change via a preference, register a preference change listener in your PreferenceFragment.


Implement onSharedPreferenceChanged():

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        if (key.equals(getString(R.string.pref_key_nighttheme))) {

            if (sharedPreferences.getBoolean(getString(R.string.pref_key_nighttheme), false)) {
                //  Night theme enabled

               darkTheme = true;

            } else {
               darkTheme = false;

            getActivity().recreate(); // This is important. It allows the theme change to take effect.

Be sure to recreate your MainActivity in onResume() if Back Navigation leads to MainActivity.

Additionally, you must check for the current theme in EVERY Activity, BEFORE super() is called in onCreate().

  isThemeDark = setDarkTheme(this);

setDarkTheme() is a helper I've created which checks the current Theme via SharedPreference. It checks if a Theme change is necessary or not.

    public static boolean setDarkTheme(Context context) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

    boolean isDarkTheme = prefs.getBoolean(context.getString(R.string.pref_key_nighttheme), false);
    context.setTheme(SettingsActivity.darkTheme ? R.style.MyDarkTheme : R.style.MyLightTheme);

    return isDarkTheme;

Here's how Night mode works in my app:

enter image description here

NOTE: Android now officially supports Night Mode via its AppCompat DayNight Theme. Here's a tutorial on the same.