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

Flutter使用Syncfusion日历添加事件不显示问题求解

问题原因

你当前的逻辑存在两个核心问题:

  • 你在EditEventsPage和CalendarWidget中分别通过InsertEvent()实例化了两个完全独立的InsertEvent对象,两个实例各自维护独立的事件列表,编辑页添加的事件只保存在编辑页的实例中,日历组件读取的是自身实例内的空列表,自然无法展示。
  • 即便使用同一个实例,你的CalendarWidget是无状态组件,没有监听事件列表的变化,新增事件后不会触发UI刷新,新增内容也无法渲染。

解决方案

方案一:通过页面传值实现状态同步(推荐,无全局状态污染)

不需要修改InsertEvent类,直接调整页面间的传值逻辑即可:

  1. 修改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);
  }
}
  1. 将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方法即可
    );
  }
}
  1. 删除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:06:08