Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update my project creating a multi theme app

Tags:

android

themes

I'd like to make a SettingsActivity 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.

EDITS

The images below are examples of SettingsActivity, 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

like image 688
Pier Avatar asked Jul 29 '16 22:07

Pier


1 Answers

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
    </style>

    <!-- 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
    </style>

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

PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);

Implement onSharedPreferenceChanged():

    @Override
    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

                getActivity().setTheme(R.style.MyDarkTheme);  
                       getActivity().getApplication().setTheme(R.style.MyDarkTheme);
               darkTheme = true;

            } else {
                getActivity().setTheme(R.style.MyLightTheme);
                getActivity().getApplication().setTheme(R.style.MyLightTheme);
               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 Newslet:

enter image description here

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

like image 176
Suleiman19 Avatar answered Sep 24 '22 14:09

Suleiman19