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

Flutter中如何将JSON转为Map<DateTime, List>适配Table Calendar插件

Convert API JSON Data to table_calendar's Map<DateTime, List> Format

Hey there! Let's walk through how to convert your API response into the Map<DateTime, List> format that table_calendar expects, and load it into your _events variable during initState.

Step 1: Confirm Your Data Models

First, let's make sure your Post model is set up correctly to parse the API's date and title fields. Here's a typical implementation:

class Post {
  final String date;
  final String title;

  Post({required this.date, required this.title});

  // Factory method to convert JSON to Post object
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      date: json['date'] as String,
      title: json['title'] as String,
    );
  }
}

Step 2: Implement the Conversion Logic in getTask

Your getTask method will fetch the API data, parse it into a list of Post objects, then convert that list into the required Map<DateTime, List<Post>> structure. Here's the updated method:

import 'dart:convert';
import 'package:http/http.dart' as http;

// Inside your State class
Map<DateTime, List<Post>> _events = {};

Future<void> getTask() async {
  try {
    // Replace with your actual API endpoint
    final response = await http.get(Uri.parse('your_api_endpoint_here'));
    
    if (response.statusCode == 200) {
      // Parse JSON response into a list of dynamic objects
      final List<dynamic> rawData = json.decode(response.body);
      // Convert raw JSON to List<Post>
      final List<Post> posts = rawData.map((json) => Post.fromJson(json)).toList();

      // Initialize a temporary map to build our events structure
      final Map<DateTime, List<Post>> tempEvents = {};

      for (final post in posts) {
        // Convert the string date from API to DateTime object
        // Adjust the parse format if your API uses a different date string (e.g., "MM/DD/YYYY")
        final DateTime rawDate = DateTime.parse(post.date);
        // table_calendar uses date-only DateTime keys (ignore time if present)
        final DateTime eventDate = DateTime(rawDate.year, rawDate.month, rawDate.day);

        // Add the post to the corresponding date in the map
        if (tempEvents.containsKey(eventDate)) {
          tempEvents[eventDate]!.add(post);
        } else {
          tempEvents[eventDate] = [post];
        }
      }

      // Update the state with our converted events
      setState(() {
        _events = tempEvents;
      });
    } else {
      throw Exception('Failed to load tasks: ${response.statusCode}');
    }
  } catch (e) {
    print('Error fetching or parsing data: $e');
    // Handle error (show snackbar, etc.)
  }
}

Step 3: Load Data in initState

Call getTask when your widget initializes to populate _events:

@override
void initState() {
  super.initState();
  getTask();
}

Step 4: Use _events with table_calendar

Finally, pass the _events map to your TableCalendar widget. You'll use the eventLoader callback to provide events for each day:

TableCalendar(
  focusedDay: DateTime.now(),
  firstDay: DateTime(2024, 1, 1),
  lastDay: DateTime(2024, 12, 31),
  // Use the eventLoader to map days to their events
  eventLoader: (day) {
    // Return empty list if no events exist for the day
    return _events[day] ?? [];
  },
  // Optional: Customize how events are displayed
  calendarBuilders: CalendarBuilders(
    markerBuilder: (context, day, events) {
      if (events.isNotEmpty) {
        return Positioned(
          bottom: 1,
          child: Container(
            width: 16,
            height: 16,
            decoration: BoxDecoration(
              color: Colors.blue,
              shape: BoxShape.circle,
            ),
            child: Center(
              child: Text(
                '${events.length}',
                style: TextStyle(color: Colors.white, fontSize: 12),
              ),
            ),
          ),
        );
      }
      return null;
    },
  ),
)

Notes for Edge Cases

  • Date Format Issues: If your API returns dates in a non-standard format (e.g., "2024/05/20" or "May 20, 2024"), use the intl package's DateFormat class to parse them correctly. Add intl to your pubspec.yaml, then:
    import 'package:intl/intl.dart';
    
    final DateTime rawDate = DateFormat('yyyy/MM/dd').parse(post.date);
    
  • Duplicate Dates: The code automatically groups multiple posts under the same date, which is exactly what table_calendar needs.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:05