如何用Java为RecyclerView填充符合条件的Firebase数据(仅男性候选人)
仅显示Firebase数据库中的男性候选人数据
我的RecyclerView目前加载了Firebase数据库中的所有数据,但我希望仅填充男性候选人的数据,尝试添加if语句筛选后页面显示空白。
当前显示效果截图:
原代码
ListViewActivity 代码
public class ListViewActivity extends AppCompatActivity { RecyclerView recyclerView; DatabaseReference databaseReference; MyAdapter myAdapter; ArrayList<EmployerInfo> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view); recyclerView = findViewById(R.id.recyclerViewList); databaseReference = FirebaseDatabase.getInstance().getReference("EmployerInfo"); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); list = new ArrayList<>(); myAdapter = new MyAdapter(this, list); recyclerView.setAdapter(myAdapter); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { for (DataSnapshot dataSnapshot: snapshot.getChildren()){ EmployerInfo employerInfo = dataSnapshot.getValue(EmployerInfo.class); list.add(employerInfo); } myAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); } }
MyAdapter 类代码
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { Context context; ArrayList<EmployerInfo> list; public MyAdapter(Context context, ArrayList<EmployerInfo> list) { this.context = context; this.list = list; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(R.layout.item, parent, false); return new MyViewHolder(v); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { EmployerInfo employerInfo = list.get(position); holder.firstName.setText(employerInfo.getName()); holder.lastName.setText(employerInfo.getSurname()); holder.gender.setText(employerInfo.getGender()); } @Override public int getItemCount() { return list.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder{ TextView firstName, lastName, gender; public MyViewHolder(@NonNull View itemView) { super(itemView); firstName =itemView.findViewById(R.id.textViewFirstName); lastName = itemView.findViewById(R.id.textViewLastName); gender = itemView.findViewById(R.id.textViewGender); } } }
尝试修改后但无效的代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view); recyclerView = findViewById(R.id.recyclerViewList); databaseReference = FirebaseDatabase.getInstance().getReference("EmployeeProfile"); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); list = new ArrayList<>(); myAdapter = new MyAdapter(this, list); recyclerView.setAdapter(myAdapter); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { for (DataSnapshot dataSnapshot: snapshot.getChildren()){ EmployerInfo employerInfo = dataSnapshot.getValue(EmployerInfo.class); if(employerInfo.getGender() == "Male"){ list.add(employerInfo); } } myAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
问题分析与解决方案
核心错误点
- 字符串比较方式错误:Java中
==比较的是对象引用地址,而非字符串内容,应该用equals()或equalsIgnoreCase()进行内容比较。 - 数据库路径不一致:修改后的代码将原节点
EmployerInfo改为EmployeeProfile,如果数据库中实际数据节点是EmployerInfo,会导致无法读取数据,页面空白。
方案一:客户端修正筛选逻辑
修改onDataChange方法,修正字符串比较逻辑,同时每次数据更新时清空旧数据避免重复加载:
databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { list.clear(); // 清空旧数据,避免重复添加 for (DataSnapshot dataSnapshot: snapshot.getChildren()){ EmployerInfo employerInfo = dataSnapshot.getValue(EmployerInfo.class); // 非空判断+正确的字符串比较 if(employerInfo != null && "Male".equals(employerInfo.getGender())){ list.add(employerInfo); } } myAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(ListViewActivity.this, "数据加载失败", Toast.LENGTH_SHORT).show(); } });
方案二:服务端筛选(更高效)
直接通过Firebase查询仅获取性别为Male的数据,减少带宽消耗,比客户端筛选更高效:
// 构建服务端查询:按gender字段筛选值为Male的数据 Query maleQuery = databaseReference.orderByChild("gender").equalTo("Male"); maleQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { list.clear(); for (DataSnapshot dataSnapshot: snapshot.getChildren()){ EmployerInfo employerInfo = dataSnapshot.getValue(EmployerInfo.class); if(employerInfo != null){ list.add(employerInfo); } } myAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(ListViewActivity.this, "数据加载失败", Toast.LENGTH_SHORT).show(); } });
注意:使用服务端查询时,需在Firebase控制台的数据库规则中为
gender字段创建索引,避免性能警告,规则示例:{ "rules": { "EmployerInfo": { ".indexOn": ["gender"] } } }
内容的提问来源于stack exchange,提问作者Arizen Bolt
相关产品推荐
相关产品推荐

