如何使用 SearchView 过滤 FirestoreRecyclerAdapter

Posted

技术标签:

【中文标题】如何使用 SearchView 过滤 FirestoreRecyclerAdapter【英文标题】:How to filter a FirestoreRecyclerAdapter with SearchView 【发布时间】:2020-10-02 17:20:20 【问题描述】: 我一直在尝试“过滤”一组使用 FirestoreRecyclerAdapter 从 Firestore 获取的数据。下面是实现场景的“适配器”:

RecyclerAdapter.java

public class IncidentsRecyclerAdapter extends FirestoreRecyclerAdapter<Incidents, IncidentsRecyclerAdapter.IncidentsHolder> implements Filterable 
    private OnItemClickListener listener;
    private ObservableSnapshotArray<Incidents> list;
    private ArrayList<Incidents> listFull;

    public IncidentsRecyclerAdapter(@NonNull FirestoreRecyclerOptions<Incidents> options) 
        super(options);
        this.list = options.getSnapshots();
        this.listFull = new ArrayList<>(options.getSnapshots());
    

    @SuppressLint("SetTextI18n")
    @Override
    protected void onBindViewHolder(@NonNull IncidentsHolder holder, int position, @NonNull Incidents model) 
        Picasso.get()
                .load(model.getIncident_image_one())
                .placeholder(R.mipmap.ic_launcher)
                .fit()
                .centerCrop()
                .into(holder.imageViewIncident);

        holder.textViewName.setText(model.getUser_name());
        holder.textViewDateTime.setText(model.getIncident_timestamp());
        holder.textViewDescription.setText(model.getIncident_location() + "/" + model.getIncident_desc());
    

    @NonNull
    @Override
    public IncidentsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.incident_item,
                parent, false);
        return new IncidentsHolder(v);
    

    @Override

    public Filter getFilter() 
        return dataFilter;
    

    private Filter dataFilter = new Filter() 
        @Override
        // Will be executed in a background thread
        protected FilterResults performFiltering(CharSequence constraint) 
            List<Incidents> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0) 
                filteredList.addAll(listFull);
             else 
                String filterPattern = constraint.toString().toLowerCase().trim();
                for (Incidents item : listFull) 
                    if(item.toString().toLowerCase().contains(filterPattern)) 
                        filteredList.add(item);
                    
                
            
            FilterResults filterResults = new FilterResults();
            filterResults.values = filteredList;
            return filterResults;
        

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            list.clear();
            list.addAll((Collection<? extends Incidents>) results.values);
            notifyDataSetChanged();
        
    ;


只要按下工具栏上的搜索图标,RecyclerView 就会消失,并且搜索过滤器会自动不起作用。

我认为我在将 Firestorecycleroptions 转换为 ArrayList 时做错了。

更新 根据link,Firebase 不支持对文本字段进行全文搜索。此外,尝试一种解决方法,我可以将FirestoreRecyclerAdapter 数据转换为原始StringListArray 类型,以便可以实现本地搜索。 Algolia/ElastiSeacrch 可能是一个难以处理的负担。 如果此更新错误或不合逻辑,请指导

【问题讨论】:

我认为这 article 可能会有所帮助。 是否可以创建 Firestorerecycleroptions 的 local copy 并在其上运行过滤器? 我建议再次查询搜索到的数据,这样会减少很多复杂性和代码 同意。但这甚至没有过滤数据,当我点击搜索图标时,回收站视图是空白的 @AlexMamo。万分感谢!!!!对于信息... 【参考方案1】:

只需从构造函数中删除 Firestorerecycleroptions 并仅使用您的列表而不调用 super():

public IncidentsRecyclerAdapter(List<Incidents> list) 
    this.list = list;
    this.listFull = new ArrayList<>(list);

【讨论】:

IncidentsRecyclerAdapter extends FirestoreRecyclerAdapter 所以这是不可能的。我要求它应该过滤通过 FirebaseUI 实现的 FirestoreRecycler

以上是关于如何使用 SearchView 过滤 FirestoreRecyclerAdapter的主要内容,如果未能解决你的问题,请参考以下文章

在使用存储在 JSON 上的 ID 进行 SearchView 过滤后,如何从 ListView 打开 Activity

SearchView 过滤和设置建议

如何更改 SearchView 默认图标?

使用 Room 和 RecyclerView 在 SearchView 中添加过滤器

已解决:SearchView 不会在 TabLayout 的每个子选项卡中进行过滤

去除searchView的黑框去除