androidpreferencefragmentandroid-night-modeandroid-dark-theme

setDefaultNightMode() only works after second call in PreferenceFragment


I am working to implement a dark mode into my app. Right now I try to switch the UI mode between light and dark using a PreferenceFragment nested inside an AppCompatActivity. The App behaves like this, starting from the light theme as a default value:

So basically everything works, but you have to select the desired value in the ListPreference twice. The code for the ListPreference:

final Preference listPreferenceDesign = findPreference(PREF_DESIGN);
listPreferenceDesign.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    @Override
    public boolean onPreferenceChange(Preference preference, Object o) {
            if (((ListPreference) preference).getValue().equals("light")) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            } else if (((ListPreference) preference).getValue().equals("dark")) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            }
            return true;
    }
});

What I tried so far:

I am thankful for further help.


Solution

  • I finally get it to work using an OnSharedPreferenceChangeListener in the parent activity. Now the code in the parent activity goes like this:

    getFragmentManager().beginTransaction().replace(R.id.settingsPlaceholderID, preferenceFragment).commit();
    SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            if (key.equals(PREF_DESIGN)) {
                if (sharedPreferences.getString(key, "light").equals("light")) {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                } else {
                    AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                }
            }
        }
    };
    
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
    

    And in the PreferenceFragment I only have:

    final Preference listPreferenceDesign = findPreference(PREF_DESIGN);
    listPreferenceDesign.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object o) {           
            return true;
        }
    });