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

SearchView输入内容后RecyclerView项消失问题求助

问题分析与解决方案

看起来你的筛选逻辑出现了两个关键问题,导致输入搜索内容后列表为空:


1. 核心问题:fullOffers未正确持有完整数据源,且初始恢复逻辑错误

  • 你在performFiltering的空约束分支里,使用filteredList.addAll(offers)来恢复原始列表,但如果之前已经执行过筛选,offers已经是筛选后的短列表,无法恢复全部数据;正确的做法应该是从fullOffers(完整数据源)中拷贝。
  • 另外,如果你的Adapter是先传入空列表、后续再动态添加数据的,fullOffers会一直保持为空——因为构造函数里只初始化一次,后续更新offers时没有同步更新fullOffers,导致筛选时遍历空列表,自然没有结果。

2. 线程错误:在后台线程调用UI操作

performFiltering方法是在后台线程执行的,直接在这里调用Toast会触发线程异常(虽然你说第一个Toast显示了,但这是不可靠的,大概率会导致崩溃),UI操作必须放在主线程执行的publishResults方法中。


修正后的完整代码

public class OffersAdapter extends RecyclerView.Adapter<OffersAdapter.ViewHolder> implements Filterable{ 
    private Context context; 
    private List<offer> offers; 
    private List<offer> fullOffers; 

    // 修正泛型参数,确保传入完整数据源并拷贝
    public OffersAdapter(List<offer> offersList, Context mContext){ 
        context = mContext; 
        // 拷贝列表,避免外部修改影响内部数据
        offers = new ArrayList<>(offersList); 
        fullOffers = new ArrayList<>(offersList); 
    }

    // 添加动态更新数据源的方法,确保fullOffers同步更新
    public void setOffers(List<offer> newOffers) {
        offers.clear();
        offers.addAll(newOffers);
        fullOffers.clear();
        fullOffers.addAll(newOffers);
        notifyDataSetChanged();
    }

    @Override
    public Filter getFilter() { 
        return exampleFilter; 
    } 

    private Filter exampleFilter = new Filter() { 
        @Override 
        protected FilterResults performFiltering(CharSequence constraint) { 
            ArrayList<offer> filteredList = new ArrayList<>(); 
            if (constraint == null || constraint.length() == 0) { 
                // 从完整数据源恢复,而不是当前的offers
                filteredList.addAll(fullOffers); 
            } else { 
                String filterPattern = constraint.toString().toLowerCase().trim(); 
                // 遍历完整数据源进行筛选
                for (offer item : fullOffers) { 
                    // 先判空避免空指针异常
                    if (item.getTitle() != null && item.getTitle().toLowerCase().contains(filterPattern)) { 
                        filteredList.add(item); 
                    } 
                } 
            } 
            FilterResults results = new FilterResults(); 
            results.values = filteredList; 
            return results; 
        } 

        @Override 
        protected void publishResults(CharSequence constraint, FilterResults results) { 
            offers.clear(); 
            // 强转成正确泛型,避免类型警告
            offers.addAll((List<offer>) results.values); 
            notifyDataSetChanged(); 
            // UI操作放在主线程的publishResults中执行
            if (offers.isEmpty()) {
                Toast.makeText(context, "未找到匹配项", Toast.LENGTH_SHORT).show();
            }
        } 
    }; 

    // 补全RecyclerView必备的ViewHolder与绑定方法
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.your_item_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        offer currentOffer = offers.get(position);
        holder.titleTextView.setText(currentOffer.getTitle());
        // 其他视图绑定逻辑
    }

    @Override
    public int getItemCount() {
        return offers != null ? offers.size() : 0;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView titleTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.title_text);
            // 初始化其他视图组件
        }
    }
}

使用注意事项

  1. 创建Adapter时,务必传入完整的数据源列表,不要传入空列表后再单独更新offers;如果需要动态加载数据,使用setOffers方法来更新,确保fullOffers同步拿到完整数据。
  2. 确保offer类的getTitle()方法能正确返回字符串,避免空指针异常。

内容的提问来源于stack exchange,提问作者Musaed Alosaimi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:56:18