Android如何通过TextView选择的日期查询数据并在RecyclerView展示
问题原因分析
- 获取TextView显示内容的方法错误:
date.toString()返回的是TextView控件的对象内存标识,不是你设置的日期文本,正确写法是date.getText().toString() - 数据查询逻辑仅在Activity初始化时执行一次,用户选中日期后不会触发重新检索逻辑,所以只能拿到初始化时的硬编码/空值对应的数据
- 每次查询新日期前未清空原有考勤列表,会导致多日期数据叠加展示
- 存在冗余代码:连续两次给
databaseReference赋值,硬编码日期的赋值逻辑可以直接删除
具体实现方案
核心修改逻辑
将考勤数据查询逻辑抽为独立公共方法,在用户完成日期选择后主动调用该方法加载对应日期的数据,同时每次加载前清空旧列表避免数据冗余。
修改后完整代码
// 全局定义列表和适配器,方便复用 private List<Attendance> attendances; private EditStaffAttendAdapter editStaffAttendAdapter; private TextView date; private RecyclerView recyclerView; private DatabaseReference databaseReference; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout_name); // 替换为你自己的布局名 date = findViewById(R.id.DateTextView); recyclerView = findViewById(R.id.staffList); recyclerView.setLayoutManager(new LinearLayoutManager(this)); attendances = new ArrayList<>(); // 初始化适配器,后续只更新数据即可,无需每次新建 editStaffAttendAdapter = new EditStaffAttendAdapter(attendances, ViewAttendActivity.this); recyclerView.setAdapter(editStaffAttendAdapter); recyclerView.setVisibility(View.GONE); date.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Calendar calendar = Calendar.getInstance(); int YEAR = calendar.get(Calendar.YEAR); int MONTH = calendar.get(Calendar.MONTH); int DATE = calendar.get(Calendar.DATE); DatePickerDialog datePickerDialog = new DatePickerDialog(ViewAttendActivity.this, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker datePicker, int year, int month, int day) { Calendar calendar1 = Calendar.getInstance(); calendar1.set(Calendar.YEAR, year); calendar1.set(Calendar.MONTH, month); calendar1.set(Calendar.DATE, day); String dateText = DateFormat.format("MM-dd-yyyy", calendar1).toString(); date.setText(dateText); // 选中日期后直接触发数据加载 loadAttendanceData(dateText); } }, YEAR, MONTH, DATE); datePickerDialog.show(); } }); // 初始化时判断是否有默认日期,没有则提示选日期 String initDate = date.getText().toString(); if (initDate.isEmpty()){ Toast.makeText(ViewAttendActivity.this, "Please Select Date First!!!", Toast.LENGTH_SHORT).show(); } else { loadAttendanceData(initDate); } } /** * 独立的考勤数据加载方法 * @param targetDate 要查询的日期,格式为MM-dd-yyyy */ private void loadAttendanceData(String targetDate) { // 加载新数据前清空旧列表,避免数据叠加 attendances.clear(); recyclerView.setVisibility(View.VISIBLE); // 直接用传入的日期查询,删除冗余的硬编码赋值 databaseReference = FirebaseDatabase.getInstance().getReference("Attendance").child(targetDate); databaseReference.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { for (DataSnapshot dataSnapshot: snapshot.getChildren()){ Attendance attendance = dataSnapshot.getValue(Attendance.class); attendances.add(attendance); } // 通知适配器数据更新,无需每次新建适配器 editStaffAttendAdapter.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(ViewAttendActivity.this, "加载失败:" + error.getMessage(), Toast.LENGTH_SHORT).show(); } }); }
注意事项
- 需确保Firebase中Attendance节点下的子节点日期格式和你代码中格式化的
MM-dd-yyyy完全一致,否则会查询不到数据 - 这里将
addValueEventListener替换为addListenerForSingleValueEvent,避免数据实时变动时频繁回调刷新列表,如果需要实时更新可以改回原来的监听方式
内容的提问来源于stack exchange,提问作者chrislam
相关产品推荐
相关产品推荐

