使用SharedPreference保存AlertDialog单选主题选项及选中状态的问题咨询
问题修复方案
核心问题原因
你的代码存在2个直接导致功能失效的错误:
- 读写SharedPreferences的文件名不统一:你定义的常量
SHARED_PREFS值为"sharedPrefs",但保存数据时硬编码传入了"SHARED_PREFS"字符串,读写操作对应了两个完全独立的SP文件,自然无法读到存储的选择。 - AlertDialog单选默认值写死:
setSingleChoiceItems的第二个参数固定传了2,不管用户之前选了什么,打开弹窗都默认选中「系统默认」选项,无法同步历史选择。
额外补充:你当前只在点击弹窗确认按钮时应用主题,Activity初始化时读取到存储的主题后没有主动应用,会导致APP重启后主题不会自动生效。
具体修改步骤
- 统一SharedPreferences读写的文件名,统一使用常量
SHARED_PREFS - 打开弹窗时根据当前存储的
selectedTheme计算对应的选中索引,作为单选框的默认选中值 - 在Activity的
onCreate方法读取到历史主题后,主动应用对应主题
修正后完整代码
String selectedTheme = "Light"; public static final String SHARED_PREFS = "sharedPrefs"; public static final String KEY_THEME = "str"; // 建议把存储键也抽成常量,避免写错 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 读取存储的主题并立即应用 SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE); selectedTheme = sharedPreferences.getString(KEY_THEME, "Light"); applyTheme(selectedTheme); // 启动时直接加载历史主题 } public void openDialog() { String[] themes = {"Light", "Dark", "System default"}; // 计算当前主题对应的选中索引 int checkedIndex = 0; switch (selectedTheme) { case "Light": checkedIndex = 0; break; case "Dark": checkedIndex = 1; break; case "System default": checkedIndex = 2; break; } AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("Choose Theme"); // 传入计算得到的默认选中索引,替换原来写死的2 builder.setSingleChoiceItems(themes, checkedIndex, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { selectedTheme = themes[which]; } }); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 修正SP文件名,使用常量不要硬编码字符串 SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(KEY_THEME, selectedTheme); editor.apply(); // 应用选中的主题 applyTheme(selectedTheme); dialog.dismiss(); } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); } // 把应用主题的逻辑抽成公共方法,避免重复代码 private void applyTheme(String theme) { if (theme.equals("Light")) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } else if (theme.equals("Dark")) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); } }
内容的提问来源于stack exchange,提问作者Vishal A.
相关产品推荐
相关产品推荐

