如何从Firebase检索指定行 实现列表点击跳转展示对应数据
实现说明
这个需求完全可以实现。你当前代码存在两个问题:一是仅存储了拼接后的展示字符串,没有保留对应位置的岗位完整数据,点击时无法获取选中行的完整信息;二是将列表点击事件绑定写在了数据回调方法内,每次数据刷新都会重复绑定监听,存在内存泄漏风险。
具体实现步骤
- 新增一个和展示列表位置一一对应的
PostJob类型列表,存储每条岗位的完整数据 - 将列表点击监听移到数据回调外层,仅绑定一次,点击时根据选中位置从PostJob列表取出对应数据
- 通过Intent将选中的岗位数据传递到新的详情Activity,在详情页取出数据渲染即可
修正后代码
列表页代码
listView = findViewById(R.id.listView); ArrayList<String> displayList = new ArrayList<>(); // 新增列表存储完整岗位对象 ArrayList<PostJob> jobDataList = new ArrayList<>(); ArrayAdapter adapter = new ArrayAdapter<String>(this, R.layout.list_job, displayList); listView.setAdapter(adapter); // 点击事件移到数据回调外,仅绑定一次 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { PostJob selectedJob = jobDataList.get(position); Intent intent = new Intent(当前页Activity.this, ViewJobActivity.class); // 传递选中的岗位对象,PostJob需实现Serializable接口 intent.putExtra("selected_job", selectedJob); startActivity(intent); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); } }); DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("postJobs"); reference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { displayList.clear(); jobDataList.clear(); for(DataSnapshot snapshot : dataSnapshot.getChildren()){ PostJob postJob = snapshot.getValue(PostJob.class); // 可选:存储数据唯一key,后续编辑/删除数据可直接使用 postJob.setJobId(snapshot.getKey()); String header = postJob.getSpecial() + " : " + postJob.getCompName(); String position = "\n" + postJob.getPosition(); String location = "\n" + postJob.getLocation(); String salary = "\nRM" + postJob.getSalaryMin() + " - RM" + postJob.getSalaryMax(); displayList.add(header + position + location + salary); jobDataList.add(postJob); } adapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 可添加加载失败的Toast提示 } });
详情页(ViewJobActivity)代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_job); // 接收传递过来的岗位数据 PostJob selectedJob = (PostJob) getIntent().getSerializableExtra("selected_job"); if (selectedJob != null) { // 将数据绑定到对应控件即可,示例: TextView headerTv = findViewById(R.id.tv_header); headerTv.setText(selectedJob.getSpecial() + " : " + selectedJob.getCompName()); TextView positionTv = findViewById(R.id.tv_position); positionTv.setText(selectedJob.getPosition()); TextView locationTv = findViewById(R.id.tv_location); locationTv.setText(selectedJob.getLocation()); TextView salaryTv = findViewById(R.id.tv_salary); salaryTv.setText(String.format("RM%s - RM%s", selectedJob.getSalaryMin(), selectedJob.getSalaryMax())); } }
注意事项
你的
PostJob类需要实现Serializable接口才能通过Intent传递,修改类定义为public class PostJob implements Serializable即可,类内原有字段无需额外改动。
如果不想传递整个对象,也可以仅传递选中项对应的Firebase数据key,在详情页重新查询单条数据渲染,两种方案都可正常实现需求。
附:原问题中的数据库结构

内容的提问来源于stack exchange,提问作者WLDN
相关产品推荐
相关产品推荐

