Flutter如何将phpMyAdmin数据展示为table_calendar日历事件
将接口返回数据加载为table_calendar日历事件的实现方案
1. 改造utils.dart的事件存储逻辑
删除原有硬编码的静态测试事件_kEventSource,将事件映射改为支持动态更新,同时新增接口数据转日历事件的加载方法。注意替换代码中Welcome类对应的日期、标题字段为你实际的字段名,如果接口返回的是日期字符串,先通过DateTime.parse()转成DateTime类型再处理。
import 'dart:collection'; import 'package:flutter/cupertino.dart'; import 'package:saajnairobi/announcementapi.dart'; import 'package:table_calendar/table_calendar.dart'; import '../advertannouncements.dart'; /// 日历事件类 class Event { final String title; // 如需更多事件属性(比如事件详情、跳转链接)直接在这里新增 const Event(this.title); @override String toString() => title; } /// 日历事件存储,Key为日期,Value为对应当天的事件列表 final kEvents = LinkedHashMap<DateTime, List<Event>>( equals: isSameDay, hashCode: getHashCode, ); int getHashCode(DateTime key) { return key.day * 1000000 + key.month * 10000 + key.year; } /// 获取日期区间内所有日期 List<DateTime> daysInRange(DateTime first, DateTime last) { final dayCount = last.difference(first).inDays + 1; return List.generate( dayCount, (index) => DateTime.utc(first.year, first.month, first.day + index), ); } final kToday = DateTime.now(); final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day); final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day); /// 拉取接口数据并转换为日历事件格式 Future<void> loadCalendarEvents() async { // 拉取公告接口数据 final List<Welcome> apiAnnouncements = await fetchadvertannouncements(); // 清空旧的事件数据 kEvents.clear(); for (final ann in apiAnnouncements) { // ========== 这里替换成你Welcome类实际的字段名 ========== // 如果接口返回的是日期字符串,先做解析:DateTime.parse(ann.dateField) DateTime rawDate = ann.eventDate; // 截断时分秒,避免时区/时间精度问题导致日期匹配失败 final DateTime eventDate = DateTime(rawDate.year, rawDate.month, rawDate.day); final String eventTitle = ann.title; // ====================================================== // 将事件按日期归类存储 if (kEvents.containsKey(eventDate)) { kEvents[eventDate]!.add(Event(eventTitle)); } else { kEvents[eventDate] = [Event(eventTitle)]; } } }
2. 改造日历页面的初始化逻辑
在日历页面的初始化状态中调用事件加载方法,数据加载完成后刷新选中日期的事件列表,避免首屏看不到数据。修改initState代码如下:
@override void initState() { super.initState(); _selectedDay = _focusedDay; // 初始给空事件列表,等接口返回后再更新 _selectedEvents = ValueNotifier([]); // 加载日历事件 loadCalendarEvents().then((_) { setState(() { _selectedEvents.value = _getEventsForDay(_selectedDay!); }); }); }
补充说明
- 如果需要支持手动刷新事件,直接在刷新回调中重新调用
loadCalendarEvents(),执行完成后调用setState更新_selectedEvents.value即可 - 日期处理必须截断时分秒部分,否则
isSameDay方法可能因为时间戳的小时、分钟、毫秒差异,无法匹配到对应日期的事件 - 如果需要在事件列表展示更多信息,直接在
Event类中新增对应属性,转换数据时赋值,之后在列表项的ListTile中取对应属性渲染即可 - 原有写死的测试事件会被接口返回的真实事件替换,如需保留测试事件可以在
loadCalendarEvents方法末尾手动追加。
内容的提问来源于stack exchange,提问作者Michael Ng'ang'a Njoroge
相关产品推荐
相关产品推荐

