使用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
相关产品推荐
相关产品推荐

