Android调用getPreferenceScreen()空引用/CheckBoxPreference为空如何解决
问题原因
- 你在
onCreate中额外创建了一个全新的SettingsFragment实例,该实例没有被添加到Fragment管理器,也没有执行onCreatePreferences生命周期方法,Preference配置没有被加载,自然拿不到PreferenceScreen和对应的CheckBoxPreference - 你之前通过事务提交添加的是另一个
SettingsFragment实例,两个实例互相独立,无法共享状态 - 直接在Activity的
onCreate中操作Fragment的View/Preference时机过早,此时Fragment还未完成初始化
修复方案
核心逻辑是把isWoman参数传递给Fragment,在Fragment内部完成Preference的状态设置,此时Preference已经加载完成,不会为空。
1. 修改Activity代码
public class Settings extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.settings_activity); // 先拿到传入的参数 boolean isWoman = true; Bundle extras = getIntent().getExtras(); if(extras != null) { isWoman = extras.getBoolean("isWoman"); } if (savedInstanceState == null) { // 创建Fragment并传递参数 SettingsFragment fragment = new SettingsFragment(); Bundle args = new Bundle(); args.putBoolean("isWoman", isWoman); fragment.setArguments(args); getSupportFragmentManager() .beginTransaction() .replace(R.id.settings, fragment) .commit(); } ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(true); } } }
2. 修改Fragment代码
public static class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); // 拿到参数 boolean isWoman = requireArguments().getBoolean("isWoman"); // 此时配置已加载,可以找到对应的Preference CheckBoxPreference pref = findPreference("pregnant"); if (pref != null) { pref.setEnabled(isWoman); } } }
注意事项
- 操作Preference必须放在
onCreatePreferences方法执行之后,此时配置已经加载完成,可以正常找到对应控件 - 不要重复创建Fragment实例,所有需要传递给Fragment的参数都通过
setArguments传递,在Fragment内部自行处理对应逻辑 - 增加非空判断可以避免极端场景下的崩溃,不要直接使用
Objects.requireNonNull强制要求非空,容易直接触发崩溃
内容的提问来源于stack exchange,提问作者duszyn_
相关产品推荐
相关产品推荐

