如何在Flutter中从SQFlite数据库加载事件到SfCalendar
解决SfCalendar加载SQFlite事件数据的方案
第一步:修正模型类的日期转换逻辑
你的数据库中start_Date和end_Date存储的是字符串,但模型类直接赋值DateTime会抛出类型错误,需要在fromMap和toMap中做类型转换:
class LeaveCalenderLeaveDetails { String leaveType; DateTime start_Date; DateTime end_Date; LeaveCalenderLeaveDetails({ required this.leaveType, required this.start_Date, required this.end_Date, }); // 从数据库字符串转DateTime factory LeaveCalenderLeaveDetails.fromMap(Map<String, dynamic> json) => LeaveCalenderLeaveDetails( leaveType: json['leaveType'] as String, start_Date: DateTime.parse(json['start_Date'] as String), end_Date: DateTime.parse(json['end_Date'] as String), ); // DateTime转字符串存入数据库 Map<String, dynamic> toMap() { return { 'leaveType': leaveType, 'start_Date': start_Date.toIso8601String(), 'end_Date': end_Date.toIso8601String(), }; } }
第二步:将数据库数据转换为SfCalendar所需的Appointment
SfCalendar依赖Appointment类型的数据源,需要把从数据库获取的LeaveCalenderLeaveDetails列表转成Appointment列表:
// 数据转换方法 List<Appointment> convertToAppointments(List<LeaveCalenderLeaveDetails> leaveList) { return leaveList.map((leave) { return Appointment( subject: leave.leaveType, startTime: leave.start_Date, endTime: leave.end_Date, // 可选:自定义事件样式 color: Colors.blueAccent, ); }).toList(); }
第三步:在页面中加载数据并渲染SfCalendar
使用FutureBuilder异步获取数据库数据,再将转换后的Appointment列表传入自定义的CalendarDataSource:
class CalendarPage extends StatelessWidget { final DatabaseHelper dbHelper = DatabaseHelper.instance; CalendarPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('请假日历')), body: FutureBuilder<List<LeaveCalenderLeaveDetails>>( future: dbHelper.getAllRecordsforCelandar(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } final leaveList = snapshot.data ?? []; final appointments = convertToAppointments(leaveList); return SfCalendar( view: CalendarView.month, dataSource: _CalendarDataSource(appointments), // 可选:开启月视图议程区 monthViewSettings: const MonthViewSettings( showAgenda: true, ), ); }, ), ); } } // 自定义日历数据源类 class _CalendarDataSource extends CalendarDataSource { _CalendarDataSource(List<Appointment> source) { appointments = source; } }
额外注意事项
- 确保数据库中存储的日期字符串是标准ISO格式(如
2024-05-20T00:00:00.000),否则DateTime.parse会解析失败。 - 跨天事件无需额外配置,只要
startTime和endTime设置正确,SfCalendar会自动识别并显示。
内容的提问来源于stack exchange,提问作者sameera
相关产品推荐
相关产品推荐

