如何在SfCalendar的议程列表中同时显示预约主题与起止时间?
SfCalendar月视图议程同时显示时间与主题解决方案
核心问题原因
当前议程仅显示主题不显示时间有两个触发点:
- TaskDataSource中
isAllDay方法统一返回true,SfCalendar默认对全天事件的议程项不展示时间段 - 未自定义议程项渲染模板,组件默认逻辑仅展示主题字段
解决步骤
方案1:调整全天事件配置(适合非全天预约场景)
如果你的预约不是真正的全天事件,直接修改isAllDay返回值为false,组件默认就会展示时间段:
@override bool isAllDay(int index) { return false; }
如果需要保留全天事件标记同时展示时间,请用方案2
方案2:自定义议程项渲染模板(灵活可控,全场景适用)
给SfCalendar添加agendaItemBuilder参数,自定义每个议程项的布局,同时展示时间和主题,修改后的SfCalendar代码如下:
Column( children: [ Expanded( child: Container( child: isLoading ? CircularProgressIndicator() : SfCalendar( view: CalendarView.month, initialSelectedDate: DateTime.now(), dataSource: TaskDataSource(taskContent), monthViewSettings: MonthViewSettings( showAgenda: true, agendaItemHeight: 40, showTrailingAndLeadingDates: false), // 新增议程项自定义构建器 agendaItemBuilder: (BuildContext context, CalendarAgendaDetails details) { final task = details.appointments.first as Task; final startTime = task.dateSched; final endTime = startTime.add(const Duration(hours: 1)); // 时间格式可自行调整,也可配合intl包做标准化格式化 final timeText = "${startTime.hour}:${startTime.minute.toString().padLeft(2, '0')} - ${endTime.hour}:${endTime.minute.toString().padLeft(2, '0')}"; return Padding( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( timeText, style: const TextStyle(fontSize: 12, color: Colors.black54), ), const SizedBox(width: 12), Text( task.title, style: const TextStyle(fontSize: 13, color: Colors.black87), ), ], ), ); }, ), ), ), ], )
可选优化:标准化时间格式化
如果需要更规范的时间显示,可引入intl包处理时间格式化:
- 在
pubspec.yaml中添加依赖:
dependencies: intl: ^0.18.1
- 代码中导入并使用:
import 'package:intl/intl.dart'; // 替换之前的时间拼接逻辑 final timeText = "${DateFormat.Hm().format(startTime)} - ${DateFormat.Hm().format(endTime)}";
内容的提问来源于stack exchange,提问作者Adrian Alejo
相关产品推荐
相关产品推荐

