如何在PreferenceFragment中立即更新日夜模式?

时间:2016-11-25 06:47:58

标签: java android android-fragments

我已经看到像Pocket这样的应用程序可以立即在设置中切换日夜模式而无需重新加载,但我无法在我自己的示例中执行此操作:

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
    }

    public static class PrefsFragment extends PreferenceFragment{
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final Context context = getActivity();
            addPreferencesFromResource(R.xml.preferences);
            SwitchPreference dayNightSwitch = (SwitchPreference) findPreference(getString(R.string.pref_day_night_key));
            dayNightSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    boolean isNightMode = (boolean) newValue;    
                    AppCompatDelegate.setDefaultNightMode(isNightMode? AppCompatDelegate.MODE_NIGHT_YES:AppCompatDelegate.MODE_NIGHT_NO);
                    return true;
                }
            });
        }
    }
}

看起来AppCompatDelegate.setDefaultNightMode根本不在PreferenceFragmentPreferenceActivity中工作。有没有办法立即更新日夜模式?

1 个答案:

答案 0 :(得分:2)

首先,您应该致电getActivity().recreate()将更改应用于当前活动。

但这还不够,因为我使用了AppCompatPreferenceActivity模板,这似乎有点不完整。我检查了AppCompatActivity source code并找到了负责处理日/夜切换的代码。

private int mThemeId = 0;

...

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    final AppCompatDelegate delegate = getDelegate();
    delegate.installViewFactory();
    delegate.onCreate(savedInstanceState);
    if (delegate.applyDayNight() && mThemeId != 0) {
        // If DayNight has been applied, we need to re-apply the theme for
        // the changes to take effect. On API 23+, we should bypass
        // setTheme(), which will no-op if the theme ID is identical to the
        // current theme ID.
        if (Build.VERSION.SDK_INT >= 23) {
            onApplyThemeResource(getTheme(), mThemeId, false);
        } else {
            setTheme(mThemeId);
        }
    }
    super.onCreate(savedInstanceState);
}

@Override
public void setTheme(@StyleRes final int resid) {
    super.setTheme(resid);
    // Keep hold of the theme id so that we can re-set it later if needed
    mThemeId = resid;
}

添加后,在首选项回调中调用getActivity().recreate()按预期工作。