在Android ListView中添加搜索栏报NullPointerException空指针错误如何解决
空指针报错原因
该报错核心是触发Context相关调用时,Context实例为空,结合你的代码,具体触发原因有3个:
- 控件初始化时机错误:你在类成员变量声明阶段直接执行
findViewById初始化EditText,此时Activity还未执行setContentView()加载布局,上下文也未完成初始化,findViewById会直接返回null,后续调用editText.addTextChangedListener()时触发空指针。 - Adapter初始化传入无效Context:如果你在类成员变量声明阶段就初始化Adapter,传入
this作为上下文,此时Activity还未完成初始化,传入的Context为null,后续Adapter调用notifyDataSetChanged()刷新视图时,内部调用Context相关方法就会触发该报错。 - 过滤逻辑缺陷:你当前的过滤逻辑是遍历原列表
mList的同时往同一个mList中添加元素,会触发并发修改异常,且如果mList未提前初始化就调用遍历逻辑,也会触发空指针。
修复方案
1. 修正EditText初始化逻辑
不要在成员变量声明阶段执行findViewById,改为在onCreate的setContentView之后初始化控件,同时增加非空判断:
// 类成员变量处只声明,不做初始化 protected EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 先加载布局,替换为你自己的布局文件名 setContentView(R.layout.your_layout_name); // 布局加载完成后再查找控件 editText = findViewById(R.id.Edittext); // 控件非空才添加监听器 if (editText != null) { editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { filter(s.toString()); } }); } }
2. 修正Adapter初始化逻辑
在onCreate中初始化Adapter,传入有效的Activity实例作为Context,不要在成员变量声明阶段初始化:
// 类成员变量处只声明Adapter和数据源 protected MyAdapter mAdapter; // 新增成员变量存储全量原始数据源,避免过滤时修改原始数据 protected ArrayList<Model> mOriginalList; protected ArrayList<Model> mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout_name); // 先初始化数据源,替换为你自己获取原始列表数据的逻辑 mList = getDataFromSource(); mOriginalList = new ArrayList<>(mList); // 备份原始全量数据 // 初始化Adapter,传入有效的Activity上下文,替换为你自己的Activity类名 mAdapter = new MyAdapter(YourActivity.this, mList); listView.setAdapter(mAdapter); // 后续再初始化EditText等控件 }
3. 修正搜索过滤逻辑
过滤时创建新的临时列表存储匹配结果,不要修改原始数据源,同时增加非空判断:
private void filter(String text){ ArrayList<Model> filteredList = new ArrayList<>(); if (text.trim().isEmpty()) { // 搜索内容为空时返回全量原始数据 filteredList.addAll(mOriginalList); } else { String lowerQuery = text.toLowerCase(Locale.ROOT); // 遍历原始全量数据做匹配,不修改原列表 for (Model item : mOriginalList) { if (item.getNome().toLowerCase(Locale.ROOT).contains(lowerQuery)) { filteredList.add(item); } } } // Adapter非空才更新列表 if (mAdapter != null) { mAdapter.filterList(filteredList); } }
4. 优化Adapter的过滤更新方法
增加列表非空判断,避免空数据传入:
public void filterList(ArrayList<Model> filteredList){ if (filteredList != null) { this.recordList = filteredList; notifyDataSetChanged(); } }
内容的提问来源于stack exchange,提问作者JhonPeter
相关产品推荐
相关产品推荐

