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

使用SearchView后RecyclerView数据消失问题求助(附代码)

FirebaseRecyclerAdapter结合SearchView无数据显示问题解决

问题描述

我完全照搬两个YouTube教程实现Firebase数据库搜索功能,但使用SearchView后RecyclerView无数据显示,即使下载教程源码也未能解决。我发现问题与StackOverflow上的类似问题相近,但我的Adapter为FirebaseRecyclerAdapter(未使用List),不知如何适配解决方案,现附上Main Activity与Adapter代码,希望解决该问题。

代码片段

Main Activity代码

public class MainActivity extends AppCompatActivity
{
   RecyclerView recview;
   myadapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("");

        recview=(RecyclerView)findViewById(R.id.recview);
        recview.setLayoutManager(new LinearLayoutManager(this));

        FirebaseRecyclerOptions<model> options =
                new FirebaseRecyclerOptions.Builder<model>()
                        .setQuery(FirebaseDatabase.getInstance().getReference().child("students"), model.class)
                        .build();

        adapter=new myadapter(options);
        recview.setAdapter(adapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        adapter.startListening();
    }

    @Override
    protected void onStop() {
        super.onStop();
        adapter.stopListening();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
         getMenuInflater().inflate(R.menu.searchmenu,menu);

         MenuItem item=menu.findItem(R.id.search);

         SearchView searchView=(SearchView)item.getActionView();

         searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
             @Override
             public boolean onQueryTextSubmit(String s) {
                 processsearch(s);
                 return false;
             }

             @Override
             public boolean onQueryTextChange(String s) {
                 processsearch(s);
                 return false;
             }
         });

        return super.onCreateOptionsMenu(menu);
    }

    private void processsearch(String s)
    {
        FirebaseRecyclerOptions<model> options =
                new FirebaseRecyclerOptions.Builder<model>()
                        .setQuery(FirebaseDatabase.getInstance().getReference().child("students").orderByChild("course").startAt(s).endAt(s+"\uf8ff"), model.class)
                        .build();

        adapter=new myadapter(options);
        adapter.startListening();
        recview.setAdapter(adapter);

    }
}

Adapter代码

public class myadapter extends FirebaseRecyclerAdapter<model,myadapter.myviewholder>
{
    public myadapter(@NonNull FirebaseRecyclerOptions<model> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull myviewholder holder, int position, @NonNull model model)
    {
       holder.name.setText(model.getName());
       holder.course.setText(model.getCourse());
       holder.email.setText(model.getEmail());
       Glide.with(holder.img.getContext()).load(model.getPurl()).into(holder.img);
    }

    @NonNull
    @Override
    public myviewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
    {
       View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.singlerow,parent,false);
       return new myviewholder(view);
    }


    class myviewholder extends RecyclerView.ViewHolder
    {
        CircleImageView img;
        TextView name,course,email;
        public myviewholder(@NonNull View itemView)
        {
            super(itemView);
            img=(CircleImageView)itemView.findViewById(R.id.img1);
            name=(TextView)itemView.findViewById(R.id.nametext);
            course=(TextView)itemView.findViewById(R.id.coursetext);
            email=(TextView)itemView.findViewById(R.id.emailtext);
        }
    }
}

解决方案

1. 先停止旧Adapter监听再创建新实例

你当前每次搜索都直接创建新Adapter,但未停止旧Adapter的监听,不仅可能导致内存泄漏,还会干扰新Adapter的数据加载。修改processsearch方法:

private void processsearch(String s)
{
    // 停止旧Adapter的监听
    adapter.stopListening();
    
    FirebaseRecyclerOptions<model> options =
            new FirebaseRecyclerOptions.Builder<model>()
                    // 统一转为小写,避免大小写不匹配导致无数据
                    .setQuery(FirebaseDatabase.getInstance().getReference().child("students")
                            .orderByChild("course")
                            .startAt(s.toLowerCase())
                            .endAt(s.toLowerCase()+"\uf8ff"), model.class)
                    .build();

    adapter = new myadapter(options);
    adapter.startListening();
    recview.setAdapter(adapter);
}

2. 配置Firebase数据库索引

Firebase实时数据库需要为查询的字段配置索引,否则查询会失效。登录Firebase控制台,找到数据库规则,添加course字段的索引:

{
  "rules": {
    "students": {
      ".indexOn": "course"
    }
  }
}

3. 处理空搜索场景

当搜索框清空时,需要恢复显示全部数据,避免RecyclerView空状态:

private void processsearch(String s)
{
    adapter.stopListening();
    Query query;
    
    if(TextUtils.isEmpty(s)){
        // 空搜索时加载全部数据
        query = FirebaseDatabase.getInstance().getReference().child("students");
    }else{
        query = FirebaseDatabase.getInstance().getReference().child("students")
                .orderByChild("course")
                .startAt(s.toLowerCase())
                .endAt(s.toLowerCase()+"\uf8ff");
    }
    
    FirebaseRecyclerOptions<model> options =
            new FirebaseRecyclerOptions.Builder<model>()
                    .setQuery(query, model.class)
                    .build();

    adapter = new myadapter(options);
    adapter.startListening();
    recview.setAdapter(adapter);
}

4. 注意事项

  • 确保数据库中students节点下的course字段值与搜索输入的格式匹配(比如统一大小写)
  • 测试时可以先使用固定字符串替换s,验证查询逻辑是否能返回数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:54:22