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

RecyclerView Filterable适配器可检索结果但无法显示问题求助

RecyclerView搜索功能实现:Filterable接口实战

我最近在开发地点搜索功能时,在RecyclerView.Adapter<>中实现了Filterable接口,用来支持按名称或区域筛选特定地点。为了调试筛选逻辑,我还在Filter的performFiltering()方法的每次迭代中记录了匹配结果,相关核心代码如下:

private class LocationsAdapter extends RecyclerView.Adapter<LocationsAdapter.MyViewHolder> implements Filterable {
    private List<Location> locationList;
    private List<Location> filteredLocationList;

    // 构造方法,初始化原始数据源和筛选结果列表
    public LocationsAdapter(List<Location> locationList) {
        this.locationList = locationList;
        this.filteredLocationList = new ArrayList<>(locationList);
    }

    // 自定义ViewHolder,绑定列表项布局控件
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView tvLocationName, tvLocationArea;

        public MyViewHolder(View itemView) {
            super(itemView);
            tvLocationName = itemView.findViewById(R.id.tv_location_name);
            tvLocationArea = itemView.findViewById(R.id.tv_location_area);
        }
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_location_list, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Location currentLocation = filteredLocationList.get(position);
        holder.tvLocationName.setText(currentLocation.getName());
        holder.tvLocationArea.setText(currentLocation.getArea());
    }

    @Override
    public int getItemCount() {
        return filteredLocationList.size();
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                // 处理搜索关键词:转为小写并去除首尾空格
                String filterKeyword = constraint.toString().toLowerCase().trim();
                FilterResults filterResults = new FilterResults();
                List<Location> tempFilteredList = new ArrayList<>();

                // 遍历原始数据源,匹配名称或区域
                for (Location location : locationList) {
                    boolean isNameMatch = location.getName().toLowerCase().contains(filterKeyword);
                    boolean isAreaMatch = location.getArea().toLowerCase().contains(filterKeyword);
                    
                    if (isNameMatch || isAreaMatch) {
                        tempFilteredList.add(location);
                        // 记录每次匹配结果,用于调试
                        Log.d("FilterDebug", "匹配地点:" + location.getName() + " | 区域:" + location.getArea());
                    }
                }

                filterResults.values = tempFilteredList;
                filterResults.count = tempFilteredList.size();
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                // 更新筛选结果列表并通知Adapter刷新
                filteredLocationList.clear();
                filteredLocationList.addAll((List<Location>) results.values);
                notifyDataSetChanged();
            }
        };
    }
}

核心要点说明:

  • filteredLocationList作为Adapter的类变量,专门存储筛选后的结果,Adapter的UI渲染逻辑完全基于这个列表
  • performFiltering()方法在后台线程执行,避免阻塞UI;这里我们统一将关键词和地点信息转为小写,实现不区分大小写的搜索
  • 每次匹配到符合条件的地点时,通过Log打印信息,方便我们验证筛选逻辑是否符合预期
  • publishResults()方法负责将筛选结果更新到Adapter的数据源,并调用notifyDataSetChanged()触发UI刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:32:20