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

Flutter SfCalendar月视图预约拖拽失效问题及功能实现咨询

解决SfCalendar月视图拖拽问题及预约框自适应内容

一、修复月视图预约拖拽功能

你的代码缺少拖拽启用配置及完整事件处理逻辑,按以下步骤修改:

  1. 开启拖拽允许开关
    在SfCalendar组件中添加allowDragAndDrop: true,这是启用拖拽的核心配置:
SfCalendar(
  allowDragAndDrop: true, // 新增该行启用拖拽
  // 其他原有属性...
)
  1. 完善拖拽结束事件处理
    仅监听onDragStart无法完成完整拖拽流程,需实现onDragEnd来更新预约的日期信息:
onDragEnd: (dragEndDetails) {
  final Appointment draggedAppointment = dragEndDetails.appointment;
  final DateTime targetDate = dragEndDetails.targetDate;

  // 根据目标日期更新预约的起止时间(示例为全天预约,可根据业务调整)
  final updatedAppointment = Appointment(
    subject: draggedAppointment.subject,
    startTime: DateTime(targetDate.year, targetDate.month, targetDate.day),
    endTime: DateTime(targetDate.year, targetDate.month, targetDate.day),
    // 补充预约的其他属性,如颜色、备注等
  );

  // 更新数据源并通知刷新
  controller.calendarDataSource.appointments.remove(draggedAppointment);
  controller.calendarDataSource.appointments.add(updatedAppointment);
  controller.calendarDataSource.notifyListeners();
},
  1. 确保数据源支持拖拽
    如果使用自定义CalendarDataSource子类,需保证canDrag方法返回true(默认已为true,若重写需注意):
class CustomCalendarDataSource extends CalendarDataSource {
  CustomCalendarDataSource(List<Appointment> appointments) : super(appointments: appointments);

  @override
  bool canDrag(Object appointment) {
    return true;
  }
}

二、实现预约框大小适配内容

修改appointmentBuilder,通过IntrinsicWidth和内边距让容器自适应文本内容:

appointmentBuilder: (context, calendarAppointmentDetails) {
  final appointment = calendarAppointmentDetails.appointments.first;
  return IntrinsicWidth(
    child: Container(
      padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
      decoration: BoxDecoration(
        color: ColorRes.yellowDark.withOpacity(1),
        borderRadius: BorderRadius.circular(5),
      ),
      alignment: Alignment.center,
      child: Text(
        appointment.subject,
        style: const TextStyle(color: ColorRes.white),
        maxLines: 1, // 可选:限制单行避免高度过高
        overflow: TextOverflow.ellipsis, // 长文本显示省略号
      ),
    ),
  );
},
  • IntrinsicWidth使容器宽度匹配文本实际宽度
  • 内边距避免文本紧贴容器边缘
  • 可根据需求调整maxLines和overflow控制长文本显示

完整修改后的代码示例

SfCalendar(
  allowDragAndDrop: true,
  onTap: (value) {},
  onViewChanged: (value){
    controller.appointment.clear();
    controller.getCalendarData(fromDate: value.visibleDates.first, toDate: value.visibleDates.last);
  },
  onDragStart: (value){
    print("======>>>  ${value.appointment}");
  },
  onDragEnd: (dragEndDetails) {
    final Appointment draggedAppointment = dragEndDetails.appointment;
    final DateTime targetDate = dragEndDetails.targetDate;

    final updatedAppointment = Appointment(
      subject: draggedAppointment.subject,
      startTime: DateTime(targetDate.year, targetDate.month, targetDate.day),
      endTime: DateTime(targetDate.year, targetDate.month, targetDate.day),
      // 补充预约其他属性
    );

    controller.calendarDataSource.appointments.remove(draggedAppointment);
    controller.calendarDataSource.appointments.add(updatedAppointment);
    controller.calendarDataSource.notifyListeners();
  },
  controller: controller.calendarController,
  view: CalendarView.month,
  selectionDecoration: BoxDecoration(
    borderRadius: BorderRadius.circular(4),
    border: Border.all(color: ColorRes.yellowDark.withOpacity(1),width: 2),
  ),
  initialDisplayDate: DateTime.now(),
  todayHighlightColor: ColorRes.yellowDark.withOpacity(1),
  monthViewSettings: const MonthViewSettings(appointmentDisplayMode: MonthAppointmentDisplayMode.appointment),
  dataSource: controller.calendarDataSource,
  appointmentBuilder: (context, calendarAppointmentDetails) {
    final appointment = calendarAppointmentDetails.appointments.first;
    return IntrinsicWidth(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
        decoration: BoxDecoration(
          color: ColorRes.yellowDark.withOpacity(1),
          borderRadius: BorderRadius.circular(5),
        ),
        alignment: Alignment.center,
        child: Text(
          appointment.subject,
          style: const TextStyle(color: ColorRes.white),
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
        ),
      ),
    );
  },
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:05:21