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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:15:42