问题
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?
回答1:
Here is the implementation in the MainActivity.java
module of the CheeseSquare repo located here:
private void setNightMode(@AppCompatDelegate.NightMode int nightMode) {
AppCompatDelegate.setDefaultNightMode(nightMode);
if (Build.VERSION.SDK_INT >= 11) {
recreate();
}
}
Here is the description of recreate() as of V25. I can't seem to find other documentation for this call - note that it was added at V11.
/* Cause this Activity to be recreated with a new instance. This results
* in essentially the same flow as when the Activity is created due to
* a configuration change -- the current instance will go through its
* lifecycle to {@link #onDestroy} and a new instance then created after it.
*/
回答2:
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;
}
});
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;
}
}
};
来源:https://stackoverflow.com/questions/41724748/cannot-switch-between-modes-in-daynight-theme-dynamically