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

如何从指定API获取数据并适配Flutter日历组件展示

从指定URL加载日历数据到Flutter日历应用的实现步骤

1. 添加网络请求依赖

在pubspec.yaml中添加http包用于网络请求:

dependencies:
  flutter:
    sdk: flutter
  syncfusion_flutter_calendar: ^25.1.39 # 请使用适配你项目的版本
  http: ^1.2.1

执行flutter pub get完成依赖安装。

2. 分析目标URL的数据结构

目标URL返回JSON数组,每个事件的核心字段对应关系:

  • Subject → Event的title
  • StartTime → Event的from
  • EndTime → Event的to
  • Description → Event的description
  • IsAllDay → Event的isAllDay
  • Color → Event的backgroundColor(十六进制字符串格式)

3. 修改Event模型,添加JSON解析能力

更新event.dart,新增fromJson构造方法实现JSON到模型的转换:

import 'package:flutter/material.dart';

class Event {
  final String title;
  final String description;
  final DateTime from;
  final DateTime to;
  final Color backgroundColor;
  final bool isAllDay;

  Event({
    required this.title,
    required this.description,
    required this.from,
    required this.to,
    required this.backgroundColor,
    required this.isAllDay,
  });

  // 从JSON对象解析Event
  factory Event.fromJson(Map<String, dynamic> json) {
    // 处理十六进制颜色字符串转Color对象
    final colorHex = json['Color'] as String;
    final color = Color(int.parse(colorHex.replaceAll('#', '0xFF')));

    return Event(
      title: json['Subject'] ?? '无标题',
      description: json['Description'] ?? '无描述',
      from: DateTime.parse(json['StartTime']),
      to: DateTime.parse(json['EndTime']),
      backgroundColor: color,
      isAllDay: json['IsAllDay'] ?? false,
    );
  }
}

4. 更新EventProvider,添加网络数据加载方法

修改event_provider.dart,新增网络请求逻辑并修复日期筛选逻辑:

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:calendar_app/model/event.dart';
import 'package:flutter/cupertino.dart';

class EventProvider extends ChangeNotifier {
  final List<Event> _events = [];

  List<Event> get events => _events;

  DateTime _selectedDate = DateTime.now();

  DateTime get selectedDate => _selectedDate;

  void setDate(DateTime date) {
    _selectedDate = date;
    notifyListeners();
  }

  // 筛选选中日期的事件
  List<Event> get eventsOfSelectedDate => _events.where((event) {
        final start = event.from;
        final end = event.to;
        return start.isBefore(_selectedDate.add(const Duration(days: 1))) &&
            end.isAfter(_selectedDate);
      }).toList();

  void addEvent(Event event) {
    _events.add(event);
    notifyListeners();
  }

  void deleteEvent(Event event) {
    _events.remove(event);
    notifyListeners();
  }

  void editEvent(Event newEvent, Event oldEvent) {
    final index = _events.indexOf(oldEvent);
    _events[index] = newEvent;
    notifyListeners();
  }

  // 从指定URL加载事件数据
  Future<void> fetchEvents() async {
    final url = Uri.parse('https://js.syncfusion.com/demos/ejservices/api/Schedule/LoadData');
    try {
      final response = await http.get(url);
      if (response.statusCode == 200) {
        final List<dynamic> jsonData = json.decode(response.body);
        final List<Event> loadedEvents = jsonData.map((item) => Event.fromJson(item)).toList();
        
        _events.clear();
        _events.addAll(loadedEvents);
        notifyListeners();
      } else {
        throw Exception('请求失败,状态码:${response.statusCode}');
      }
    } catch (e) {
      print('加载事件失败:$e');
      // 可在此添加用户可见的错误提示逻辑
    }
  }
}

5. 在UI页面中加载并展示数据

在日历页面的初始化阶段调用数据加载方法,将数据传入Syncfusion日历组件:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import 'package:calendar_app/model/event_data_source.dart';
import 'package:calendar_app/provider/event_provider.dart';

class CalendarPage extends StatefulWidget {
  const CalendarPage({super.key});

  @override
  State<CalendarPage> createState() => _CalendarPageState();
}

class _CalendarPageState extends State<CalendarPage> {
  @override
  void initState() {
    super.initState();
    // 初始化时加载网络事件
    Provider.of<EventProvider>(context, listen: false).fetchEvents();
  }

  @override
  Widget build(BuildContext context) {
    final provider = Provider.of<EventProvider>(context);
    return Scaffold(
      appBar: AppBar(title: const Text('日历')),
      body: SfCalendar(
        view: CalendarView.month,
        dataSource: EventDataSource(provider.events),
        // 可选:添加事件点击交互
        onTap: (details) {
          // 处理事件点击逻辑
        },
      ),
    );
  }
}

确保应用根节点已配置ChangeNotifierProvider(示例main.dart):

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:calendar_app/provider/event_provider.dart';
import 'package:calendar_app/screens/calendar_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => EventProvider(),
      child: MaterialApp(
        title: '日历应用',
        theme: ThemeData(primarySwatch: Colors.blue),
        home: const CalendarPage(),
      ),
    );
  }
}

注意事项

  • 需处理无网络、请求超时等异常场景,可添加加载状态提示
  • 若存在时区问题,可将解析后的时间转换为本地时区
  • 确保Syncfusion Calendar版本与项目依赖兼容

内容的提问来源于stack exchange,提问作者bongoclavour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:54:20