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); // 初始化其他视图组件 } } }
使用注意事项
- 创建Adapter时,务必传入完整的数据源列表,不要传入空列表后再单独更新
offers;如果需要动态加载数据,使用setOffers方法来更新,确保fullOffers同步拿到完整数据。 - 确保
offer类的getTitle()方法能正确返回字符串,避免空指针异常。
内容的提问来源于stack exchange,提问作者Musaed Alosaimi
相关产品推荐
相关产品推荐

