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

Flutter如何将API返回的时间数据展示到CupertinoDatePicker组件中

解决方案

前置修正说明

  • 你原有的异步请求逻辑缺少UI刷新触发,需配合StatefulWidget使用setState更新状态
  • 原有请求方法内存在变量名冲突(入参date和内部定义的DateTime date重名),实际使用时请修正避免报错
  • 系统原生CupertinoDatePicker不支持直接自定义可选时间集合,这里提供两种落地方案

方案1:原生CupertinoDatePicker+选中校验(改动最小)

第一步:调整状态定义与请求逻辑

// 替换原dynamic类型定义,明确类型
List<dynamic> timeSlotData = [];
// 存储接口返回的所有可用时间槽
List<DateTime> availableSlots = [];
// 初始化默认选中时间
DateTime initialDate = DateTime.now();

timeSlotUsingIdAndDate(String id, String date) {
  apiManager.timeSlotByIdAndDate(id, date).then((value) {
    timeSlotData.add(value);
    // 批量转换接口返回的时间为DateTime类型
    availableSlots = timeSlotData[0].data!.timeSlots!.map((slot) {
      return DateTime.parse(slot.slotTiming.toString());
    }).toList();
    // 把第一个可用时间设为默认选中值
    if (availableSlots.isNotEmpty) {
      initialDate = availableSlots.first;
    }
    // 刷新UI
    setState(() {});
  });
}

第二步:调整组件逻辑,新增选中校验

CupertinoDatePicker(
  backgroundColor: Colors.transparent,
  use24hFormat: false,
  mode: CupertinoDatePickerMode.time,
  initialDateTime: initialDate,
  minuteInterval: 30, // 需和接口返回的时间槽间隔保持一致
  onDateTimeChanged: (DateTime selected) {
    // 校验选中时间是否在可用时间槽内
    bool isValid = availableSlots.any((slot) =>
        slot.hour == selected.hour && slot.minute == selected.minute);
    if (isValid) {
      // 合法时间执行业务逻辑
      print(selected.hour);
      print(selected.minute);
    } else {
      // 不合法可自动校正到最近的可用时间,或者弹出提示
      // 示例:自动校正到最近的时间
      DateTime nearestSlot = availableSlots.reduce((a, b) =>
          a.difference(selected).abs() < b.difference(selected).abs()
              ? a
              : b);
      // 可配合状态管理重置选中时间
    }
  }
)

方案2:自定义CupertinoPicker实现完全匹配时间槽(无多余可选时间,更贴合需求)

直接用CupertinoPicker自己构建可选选项,完全使用接口返回的时间,不会出现不可选的时间:

CupertinoPicker(
  backgroundColor: Colors.transparent,
  itemExtent: 32,
  onSelectedItemChanged: (index) {
    DateTime selected = availableSlots[index];
    // 直接执行业务逻辑
    print(selected.hour);
    print(selected.minute);
  },
  children: availableSlots.map((slot) {
    // 格式化时间展示文本,可自定义格式
    String timeText = "${slot.hour > 12 ? slot.hour -12 : slot.hour}:${slot.minute.toString().padLeft(2,'0')} ${slot.hour >=12 ? 'PM' : 'AM'}";
    return Center(
      child: Text(timeText),
    );
  }).toList(),
)

效果参考

效果图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:24:10