SearchView过滤RecyclerView条目时删除搜索内容无法恢复原列表问题
问题根因
代码的核心问题出在AdapterPazienti的filter过滤逻辑中:
- 计算得到过滤结果后,没有将新的列表赋值给Adapter用来渲染列表的成员变量
mValues,仅调用notifyDataSetChanged()不会触发列表内容变更,因为实际渲染的数据源没有变化 - 存在隐藏风险:当前
mValues直接引用全局的Pazienti.ITEMS,如果过滤逻辑直接修改mValues会损坏原始全量数据,需要单独备份全量原始数据
修复方案
第一步:修改Adapter成员变量,新增原始数据备份
修改AdapterPazienti的成员变量定义,新增全量原始数据备份字段:
// 当前渲染用的列表数据 private List<Pazienti.PazientiItem> mValues; // 备份全量原始列表数据,过滤逻辑基于该备份计算结果 private List<Pazienti.PazientiItem> mOriginalValues; private final FragmentListaPazienti.OnListFragmentInteractionListener mListener;
第二步:修改构造方法,初始化原始数据备份
在构造方法中对全量原始数据做深拷贝备份:
public AdapterPazienti(List<Pazienti.PazientiItem> items, FragmentListaPazienti.OnListFragmentInteractionListener listener) { mValues = items; // 深拷贝原始数据做备份,避免过滤操作损坏原始数据源 mOriginalValues = new ArrayList<>(items); mListener = listener; }
第三步:重写filter过滤逻辑,更新渲染数据源
修改filter方法,将过滤后的结果赋值给mValues后再通知列表刷新:
public void filter(String text) { List<Pazienti.PazientiItem> filteredList = new ArrayList<>(); if(text.isEmpty()){ // 搜索内容为空时,直接恢复全量原始数据 filteredList.addAll(mOriginalValues); } else{ text = text.toLowerCase(); // 基于原始全量数据做过滤,避免过滤多次后数据丢失 for(Pazienti.PazientiItem item: mOriginalValues){ if(item.nome.toLowerCase().contains(text) || item.cognome.toLowerCase().contains(text)){ filteredList.add(item); } } } // 更新Adapter当前渲染用的数据源 mValues = filteredList; // 通知RecyclerView刷新 notifyDataSetChanged(); }
注意事项
如果后续业务逻辑中有新增、删除、修改患者数据的操作,需要同步更新mOriginalValues备份,保证过滤结果和最新业务数据一致。
内容的提问来源于stack exchange,提问作者Pasquale Serra
相关产品推荐
相关产品推荐

