SwitchPreferenceCompat设置setOnPreferenceChangeListener时应用崩溃如何解决?
问题原因及修复方案
核心崩溃原因
你触发空指针是因为switch_darkmode变量为null,findPreference没有找到对应的控件,具体有两个常见诱因:
1. findPreference入参写法错误
XML里写app:key="@string/darkmode"时,系统会自动解析@string/darkmode对应的实际字符串作为控件key,但Java代码里直接传入字符串"@string/darkmode"不会触发资源解析,系统会直接把"@string/darkmode"当做key去查询,自然匹配不到XML里的控件,返回null。
2. 未先加载Preference配置就查询控件
要确保你在onCreatePreferences方法中,先调用setPreferencesFromResource(R.xml.你的配置文件名, null)加载XML配置,再执行findPreference逻辑,否则还没加载控件就查询也会返回null。
附带逻辑问题
你当前写的OnPreferenceChangeListener里还有两处逻辑错误:
- 回调方法里直接取
switch_darkmode.isChecked()拿到的是修改之前的旧状态,会导致你的暗黑模式切换逻辑完全反向 - 回调返回
false会导致Preference的选中状态不会更新,用户点击开关后UI不会变化
修复后代码参考
SettingsFragment 修正代码
@Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // 第一步:先加载XML配置,必须放在findPreference之前 setPreferencesFromResource(R.xml.你的settings配置文件名, rootKey); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); // 第二步:正确获取string资源对应的key值,不要直接写"@string/darkmode" String darkModeKey = getResources().getString(R.string.darkmode); SwitchPreferenceCompat switch_darkmode = (SwitchPreferenceCompat) findPreference(darkModeKey); if(switch_darkmode != null) { // 加非空判断更稳妥 switch_darkmode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { // 直接用回调返回的newValue取最新状态,不要查旧的isChecked boolean isDarkModeOn = (boolean) newValue; if (isDarkModeOn) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); // bottomNavigationView.setBackgroundResource(R.drawable.rounded_nav_darkmode); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); // bottomNavigationView.setBackgroundResource(R.drawable.rounded_nav); } return true; // 必须返回true让Preference更新选中状态 } }); } }
内容的提问来源于stack exchange,提问作者Motivazia
相关产品推荐
相关产品推荐

