Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot switch between modes in DayNight theme dynamically

I implemented the DayNight theme in my app and added a setting to switch between day and night mode, but I'm not able to switch between modes dynamically without a restart.

If I use setDefaultNightMode() after the setting has been changed, the settings activity doesn't change mode, but the activities in the backstack do. If I additionally use setLocalNightMode() the settings activity gets recreated and changes its mode, but now the activities in the backstack don't. I could not find a way to accomplish both. Is there a way to do this?

like image 895
Özgür Avatar asked Jan 18 '17 16:01

Özgür


1 Answers

I got it to work, here is my code and screen record. Activities in the backstack are also changing their themes.

findPreference(getString(R.string.pref_key_night_mode)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if ((Boolean) newValue) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            }
            getDelegate().applyDayNight();
            recreate();
            return true;
        }

    });

record

Update

The solution above worked for Android 4.4 well, but preserved previous DayNight state in backstack on Android 7.1.

I've added manual check for night mode setting change in onResume:

@Override
protected void onResume() {
    super.onResume();
    if (mApplyNightMode) {
        mApplyNightMode = false;
        getDelegate().setLocalNightMode(PeshkaPreferences.getNightModeEnabled(this) ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
        getDelegate().applyDayNight();
        recreate();
    }
}

and added OnSharedPreferencesChangeListener:

protected OnSharedPreferenceChangeListener mPreferencesListener = new OnSharedPreferenceChangeListener() {

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(getString(R.string.pref_key_night_mode))) {
            mApplyNightMode = true;
        }
    }
};
like image 117
Artem Mostyaev Avatar answered Oct 26 '22 07:10

Artem Mostyaev