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

Android Studio结合Firestore实现日历按日期筛选用药提醒并展示到RecyclerView

问题解决方案

该需求完全可实现,你目前的实现逻辑存在多处不合理的地方,导致筛选效果不符合预期,可按以下方案修正:

现有代码存在的问题

  • 在onBindViewHolder中通过设置View.GONE隐藏不符合条件的item的方式不规范,会导致RecyclerView出现空白占位、滚动异常等问题,且列表计数仍为全量数据长度,并未实现真正的筛选。
  • 每次切换选中日期都重新调用setAdapter重复绑定适配器,效率极低,没有必要。
  • 日期对比逻辑错误:你拿holder.StartDate.toString()(TextView的文本内容)做对比,正确的做法是直接取数据源中存储的日期字段对比,且需保证两侧日期格式完全一致,否则会出现匹配失败的问题。

修正方案

步骤1:改造适配器,新增筛选逻辑

适配器单独维护全量数据和筛选后的数据列表,不要直接使用全局的全量数据源:

public class MyMedicationAdapter extends RecyclerView.Adapter<MyMedicationAdapter.MyViewHolder> {
    // 存储从Firestore获取的全量用药数据
    private List<medication_info> allMedicationList;
    // 存储筛选后待展示的用药数据
    private List<medication_info> filteredList = new ArrayList<>();

    // 构造方法传入全量数据
    public MyMedicationAdapter(List<medication_info> allList) {
        this.allMedicationList = allList;
    }

    // 对外暴露的日期筛选方法,切换日期时调用
    public void filterByDate(String selectedDate) {
        filteredList.clear();
        for (medication_info info : allMedicationList) {
            // 直接取数据源中的日期字段对比,无需通过View获取
            if (info.StartDate.equals(selectedDate)) {
                filteredList.add(info);
            }
        }
        // 通知适配器数据变更,刷新列表
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        // 返回筛选后的列表长度,而非全量数据长度
        return filteredList.size();
    }

    @Override
    public void onBindViewHolder(@NonNull MyMedicationAdapter.MyViewHolder holder, int position) {
        medication_info medication_info = filteredList.get(position);
        holder.InventoryMeds.setText(medication_info.InventoryMeds);
        holder.Medication.setText(medication_info.Medication);
        holder.StartDate.setText(medication_info.StartDate);
        holder.Time.setText(medication_info.Time);
        // 删除原有设置可见性的逻辑,筛选后的数据全部需要展示
    }

    // 其余ViewHolder初始化等原有代码保持不变即可
}

步骤2:修改日期选择监听逻辑

只在页面初始化时绑定一次适配器,切换日期时直接调用适配器的筛选方法即可:

// 页面初始化时仅绑定一次适配器,无需每次切换日期重复设置
myAdapter = new MyMedicationAdapter(userArrayList);
recyclerView1.setAdapter(myAdapter);

calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
    @Override
    public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
        month += 1;
        // 注意:此处生成的日期格式必须和Firestore中存储的StartDate字段格式完全一致
        // 如果存储的日期带前导零,可使用String.format补零:String selectedDate = String.format("%02d/%02d/%d", dayOfMonth, month, year);
        String selectedDate = dayOfMonth + "/" + month + "/" + year;
        Log.d("Calendar", "Selected day change " + selectedDate);
        // 调用适配器筛选方法
        myAdapter.filterByDate(selectedDate);
    }
});

注意事项

  • 必须保证Firestore中存储的StartDate字段格式,和选中日期时生成的selectedDate格式完全一致,避免因格式差异导致匹配失败。如果有条件建议统一使用LocalDate对象或者时间戳做对比,比字符串对比更稳妥。
  • 如果需要默认展示当前日期的用药数据,可在页面初始化、拿到Firestore全量数据后,主动调用一次filterByDate方法传入当前日期即可。

内容的提问来源于stack exchange,提问作者Lance Quinto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:15:03