You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView搜索功能异常:清空搜索栏后初始列表丢失,无法再次搜索

问题分析与修复方案

你的问题核心出在两个关键地方:RecyclerView绑定数据时用错了列表,以及过滤时直接赋值列表引用而非复制内容。让我们一步步解决:

1. 最关键的错误:onBindViewHolder使用了initialList而非filteredList

你当前的代码在绑定列表项时,始终从initialList取数据,但getItemCount()返回的是filteredList的长度。这会导致两个问题:

  • 过滤后的结果显示的是初始列表的前N项(N为过滤后的数量),而非真正的过滤结果
  • 当清空搜索栏时,即使filteredList指向了initialList,如果后续initialList被修改,filteredList也会跟着变化(因为是同一个引用)

修复代码:

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    // 把initialList改成filteredList,确保显示的是过滤后的内容
    final ModelMake dataAdapter = filteredList.get(position);
    viewHolder.itemName.setText(dataAdapter.getmName());
    viewHolder.itemId.setText(dataAdapter.getmId());
}

2. 过滤时直接赋值引用导致的清空问题

在performFiltering中,当清空搜索栏时你直接写了filteredList = initialList;,这是把filteredList的引用指向了initialList,两者共享同一个列表对象。如果后续initialList被clear()(比如调用updateModels时),filteredList也会被清空。

正确的做法是复制initialList的内容到新的列表,而非直接引用:

修复后的performFiltering方法:

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String charString = charSequence.toString();
            // 创建临时列表存储过滤结果
            List<ModelMake> tempFilteredList = new ArrayList<>();
            
            if (charString.isEmpty()) {
                // 清空搜索时,复制初始列表的所有内容
                tempFilteredList.addAll(initialList);
            } else {
                // 搜索逻辑不变
                for (ModelMake row : initialList) {
                    if (row.getmName().toLowerCase().contains(charString.toLowerCase())) {
                        tempFilteredList.add(row);
                    }
                }
            }
            
            FilterResults filterResults = new FilterResults();
            filterResults.values = tempFilteredList;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
            filteredList = (ArrayList<ModelMake>) filterResults.values;
            notifyDataSetChanged();
        }
    };
}

3. 优化updateModels方法(可选但建议)

确保每次更新数据时,filteredList和initialList内容一致,避免初始状态下显示异常:

public void updateModels(List<ModelMake> newModels) {
    initialList.clear();
    initialList.addAll(newModels);
    // 同步filteredList为初始列表的副本
    filteredList.clear();
    filteredList.addAll(initialList);
    notifyDataSetChanged();
}

为什么这些修改能解决问题?

  • 绑定数据时使用filteredList,确保显示的内容始终和当前过滤结果一致
  • 过滤时复制列表内容,让filteredList成为独立的对象,不再受initialList修改的影响
  • 更新数据时同步两个列表,保证初始状态下显示完整的API数据

现在测试一下:首次搜索会正确显示过滤结果,清空搜索栏后,filteredList会被填充initialList的所有内容,RecyclerView也会正确显示初始列表。

内容的提问来源于stack exchange,提问作者Kumza Ion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 01:13:12