【问题标题】:Cannot switch between modes in DayNight theme dynamically无法在 DayNight 主题中动态切换模式
【发布时间】:2018-05-18 20:48:00
【问题描述】:

我在我的应用程序中实现了 DayNight 主题,并添加了在白天和夜间模式之间切换的设置,但我无法在不重新启动的情况下动态切换模式。

如果我在设置更改后使用setDefaultNightMode(),设置活动不会更改模式,但后台堆栈中的活动会。如果我另外使用setLocalNightMode(),设置活动会重新创建并更改其模式,但现在后台堆栈中的活动不会。我找不到实现这两者的方法。有没有办法做到这一点?

【问题讨论】:

    标签: android themes android-support-library


    【解决方案1】:

    这是位于hereCheeseSquare repo 的MainActivity.java 模块中的实现:

    private void setNightMode(@AppCompatDelegate.NightMode int nightMode) {
        AppCompatDelegate.setDefaultNightMode(nightMode);
    
        if (Build.VERSION.SDK_INT >= 11) {
            recreate();
        }
    }
    

    这是从 V25 开始对 recreate() 的描述。我似乎找不到此调用的其他文档 - 请注意,它是在 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.
     */
    

    【讨论】:

    • 如果您在 MainActivity 中执行此操作,它可以工作,但如果您在另一个 Activity 中执行此操作,MainActivity 在后台堆栈中,问题仍然存在。
    • 对我有用的是通过关闭清单文件中的历史记录来“关闭”后台堆栈。将android:noHistory="true" 添加到您的活动中,如下所述:stackoverflow.com/questions/5794506/…
    【解决方案2】:

    我让它工作了,这是我的代码和屏幕记录。 backstack 中的活动也在改变他们的主题。

    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;
            }
    
        });
    

    更新

    上述解决方案适用于 Android 4.4,但在 Android 7.1 的后台堆栈中保留了先前的 DayNight 状态。

    我在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();
        }
    }
    

    并添加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;
            }
        }
    };
    

    【讨论】:

    • 也许你应该根据当前的更新更新你的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 2020-06-14
    • 2015-06-17
    • 2019-03-06
    相关资源
    最近更新 更多