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:
getActivity.recreate()
before the return true;
statementgetActivity.recreate()
after a short delay using a Handler
this.recreate()
in the onResume()
method of the parent Activity when a boolean changedDesignSetting
was trueI am thankful for further help.
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;
}
});