Cannot switch between modes in DayNight theme dynamically

此生再无相见时 提交于 2020-04-08 09:32:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!