Flutter使用Syncfusion日历添加事件不显示问题求解
问题原因
你当前的逻辑存在两个核心问题:
- 你在
EditEventsPage和CalendarWidget中分别通过InsertEvent()实例化了两个完全独立的InsertEvent对象,两个实例各自维护独立的事件列表,编辑页添加的事件只保存在编辑页的实例中,日历组件读取的是自身实例内的空列表,自然无法展示。 - 即便使用同一个实例,你的
CalendarWidget是无状态组件,没有监听事件列表的变化,新增事件后不会触发UI刷新,新增内容也无法渲染。
解决方案
方案一:通过页面传值实现状态同步(推荐,无全局状态污染)
不需要修改InsertEvent类,直接调整页面间的传值逻辑即可:
- 修改
saveEvent方法,将构造好的事件作为返回值传给上一级页面:
Future saveEvent() async { final isValid = _formKey.currentState!.validate(); if (isValid) { final event = Events( title: titleController.text, details: 'testing 1 2 3', from: fromDate, to: toDate, isAllday: false, ); // 新增事件作为返回值回传 Navigator.of(context).pop(event); } }
- 将
CalendarWidget改为有状态组件,监听编辑页的返回结果,更新事件列表后触发UI刷新:
class CalendarWidget extends StatefulWidget { @override _CalendarWidgetState createState() => _CalendarWidgetState(); } class _CalendarWidgetState extends State<CalendarWidget> { // 仅在日历页维护一个InsertEvent实例 final InsertEvent eventInstance = InsertEvent(); late EventDataSource _dataSource; @override void initState() { super.initState(); _dataSource = EventDataSource(eventInstance.events); } // 调用这个方法跳转到编辑页 void _openEditPage() async { // 接收编辑页返回的新增事件 final Events? newEvent = await Navigator.push( context, MaterialPageRoute(builder: (context) => const EditEventsPage()), ); if (newEvent != null) { // 新增事件到当前实例的列表 eventInstance.addEvent(newEvent); // 刷新日历数据源 setState(() { _dataSource = EventDataSource(eventInstance.events); // 性能更优的写法:直接通知数据源新增了事件,不需要重新构造整个数据源 // _dataSource.notifyListeners(CalendarDataSourceAction.add, [newEvent]); }); } } @override Widget build(BuildContext context) { return SfCalendar( dataSource: _dataSource, // 原有日历配置不变,打开编辑页的按钮绑定上面的_openEditPage方法即可 ); } }
- 删除
EditEventsPage中insertEventInstance相关的代码,不需要在编辑页维护实例。
方案二:通过单例模式实现全局事件共享
如果需要在多页面共享事件列表,可以把InsertEvent改成单例类,保证全局只有一个实例:
class InsertEvent { // 全局唯一实例 static final InsertEvent _singleton = InsertEvent._internal(); factory InsertEvent() => _singleton; InsertEvent._internal(); final List<Events> _events = []; List<Events> get events => _events; void addEvent(Events event) { _events.add(event); } }
之后依然需要将CalendarWidget改为有状态组件,编辑页关闭后刷新数据源即可,步骤和方案一的第二步一致。
内容的提问来源于stack exchange,提问作者coderhelp
相关产品推荐
相关产品推荐

