How to fetch a list of maps to a calendar? [Flutter]

后端 未结 2 1427
陌清茗
陌清茗 2021-01-23 06:40

I have a json object here -

{
    \"error\": \"0\",
    \"message\": \"Got it!\",
    \"data\": [
        {
            \"status\": false,
            \"_id\":          


        
相关标签:
2条回答
  • 2021-01-23 07:28

    You can copy paste run full code below
    Simulate API call with 3 seconds delay
    Suppose you have two event on 12/29 and 12/30 , then parse with Event event = eventFromJson(responseString); and return mapFetch after for loop
    You can get full Event class define in full code

    code snippet

    WidgetsBinding.instance.addPostFrameCallback((_) {
          getTask().then((val) => setState(() {
                _events = val;
              }));
    
        });
    
    ...
    Future<Map<DateTime, List>> getTask() async {
        Map<DateTime, List> mapFetch = {};
    
        await Future.delayed(const Duration(seconds: 3), () {});
    
        /*String link = baseURL + fetchTodoByDate;
        var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
        if (res.statusCode == 200) {
          // need help in creating fetch logic here
        }*/
    
        String responseString = '''
        {
        "error": "0",
        "message": "Got it!",
        "data": [
            {
                "status": false,
                "_id": "5e04a27692928701258b9b06",
                "group_id": "5df8aaae2f85481f6e31db59",
                "date": "2019-12-29T00:00:00.000Z",
                "title": "new task",
                "priority": 5,
                "description": "just a description",
                "tasks": [],
                "created_date": "2019-12-26T12:07:18.301Z",
                "__v": 0
            },
            {
                "status": false,
                "_id": "5e04a27692928701258b9b06",
                "group_id": "5df8aaae2f85481f6e31db59",
                "date": "2019-12-30T00:00:00.000Z",
                "title": "abc",
                "priority": 5,
                "description": "just a description",
                "tasks": [],
                "created_date": "2019-12-26T12:07:18.301Z",
                "__v": 0
            }
        ]
    }
        ''';
    
        Event event = eventFromJson(responseString);
    
        for (int i = 0; i < event.data.length; i++) {
          mapFetch[event.data[i].date] = [event.data[i].title];
        }
    
        return mapFetch;
      }
    

    working demo

    full code

    import 'package:flutter/material.dart';
    import 'package:table_calendar/table_calendar.dart';
    // To parse this JSON data, do
    //
    //     final event = eventFromJson(jsonString);
    
    import 'dart:convert';
    
    Event eventFromJson(String str) => Event.fromJson(json.decode(str));
    
    String eventToJson(Event data) => json.encode(data.toJson());
    
    class Event {
      String error;
      String message;
      List<Datum> data;
    
      Event({
        this.error,
        this.message,
        this.data,
      });
    
      factory Event.fromJson(Map<String, dynamic> json) => Event(
            error: json["error"],
            message: json["message"],
            data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
          );
    
      Map<String, dynamic> toJson() => {
            "error": error,
            "message": message,
            "data": List<dynamic>.from(data.map((x) => x.toJson())),
          };
    }
    
    class Datum {
      bool status;
      String id;
      String groupId;
      DateTime date;
      String title;
      int priority;
      String description;
      List<dynamic> tasks;
      DateTime createdDate;
      int v;
    
      Datum({
        this.status,
        this.id,
        this.groupId,
        this.date,
        this.title,
        this.priority,
        this.description,
        this.tasks,
        this.createdDate,
        this.v,
      });
    
      factory Datum.fromJson(Map<String, dynamic> json) => Datum(
            status: json["status"],
            id: json["_id"],
            groupId: json["group_id"],
            date: DateTime.parse(json["date"]),
            title: json["title"],
            priority: json["priority"],
            description: json["description"],
            tasks: List<dynamic>.from(json["tasks"].map((x) => x)),
            createdDate: DateTime.parse(json["created_date"]),
            v: json["__v"],
          );
    
      Map<String, dynamic> toJson() => {
            "status": status,
            "_id": id,
            "group_id": groupId,
            "date": date.toIso8601String(),
            "title": title,
            "priority": priority,
            "description": description,
            "tasks": List<dynamic>.from(tasks.map((x) => x)),
            "created_date": createdDate.toIso8601String(),
            "__v": v,
          };
    }
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      List _selectedEvents;
      int _counter = 0;
      Map<DateTime, List> _events;
      CalendarController _calendarController;
      AnimationController _animationController;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      Future<Map<DateTime, List>> getTask() async {
        Map<DateTime, List> mapFetch = {};
    
        await Future.delayed(const Duration(seconds: 3), () {});
    
        /*String link = baseURL + fetchTodoByDate;
        var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
        if (res.statusCode == 200) {
          // need help in creating fetch logic here
        }*/
    
        String responseString = '''
        {
        "error": "0",
        "message": "Got it!",
        "data": [
            {
                "status": false,
                "_id": "5e04a27692928701258b9b06",
                "group_id": "5df8aaae2f85481f6e31db59",
                "date": "2019-12-29T00:00:00.000Z",
                "title": "new task",
                "priority": 5,
                "description": "just a description",
                "tasks": [],
                "created_date": "2019-12-26T12:07:18.301Z",
                "__v": 0
            },
            {
                "status": false,
                "_id": "5e04a27692928701258b9b06",
                "group_id": "5df8aaae2f85481f6e31db59",
                "date": "2019-12-30T00:00:00.000Z",
                "title": "abc",
                "priority": 5,
                "description": "just a description",
                "tasks": [],
                "created_date": "2019-12-26T12:07:18.301Z",
                "__v": 0
            }
        ]
    }
        ''';
    
        Event event = eventFromJson(responseString);
    
        for (int i = 0; i < event.data.length; i++) {
          mapFetch[event.data[i].date] = [event.data[i].title];
        }
    
        return mapFetch;
      }
    
      void _onDaySelected(DateTime day, List events) {
        print('CALLBACK: _onDaySelected');
        setState(() {
          _selectedEvents = events;
        });
      }
    
      @override
      void initState() {
        final _selectedDay = DateTime.now();
        _selectedEvents = [];
        _calendarController = CalendarController();
        _animationController = AnimationController(
          vsync: this,
          duration: const Duration(milliseconds: 400),
        );
    
        _animationController.forward();
        WidgetsBinding.instance.addPostFrameCallback((_) {
          getTask().then((val) => setState(() {
                _events = val;
              }));
          //print( ' ${_events.toString()} ');
        });
        super.initState();
      }
    
      @override
      void dispose() {
        _calendarController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                _buildTableCalendarWithBuilders(),
                const SizedBox(height: 8.0),
                const SizedBox(height: 8.0),
                Expanded(child: _buildEventList()),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    
      Widget _buildTableCalendarWithBuilders() {
        return TableCalendar(
          //locale: 'pl_PL',
          calendarController: _calendarController,
          events: _events,
          //holidays: _holidays,
          initialCalendarFormat: CalendarFormat.month,
          formatAnimation: FormatAnimation.slide,
          startingDayOfWeek: StartingDayOfWeek.sunday,
          availableGestures: AvailableGestures.all,
          availableCalendarFormats: const {
            CalendarFormat.month: '',
            CalendarFormat.week: '',
          },
          calendarStyle: CalendarStyle(
            outsideDaysVisible: false,
            weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
            holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
          ),
          daysOfWeekStyle: DaysOfWeekStyle(
            weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
          ),
          headerStyle: HeaderStyle(
            centerHeaderTitle: true,
            formatButtonVisible: false,
          ),
          builders: CalendarBuilders(
            selectedDayBuilder: (context, date, _) {
              return FadeTransition(
                opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
                child: Container(
                  margin: const EdgeInsets.all(4.0),
                  padding: const EdgeInsets.only(top: 5.0, left: 6.0),
                  color: Colors.deepOrange[300],
                  width: 100,
                  height: 100,
                  child: Text(
                    '${date.day}',
                    style: TextStyle().copyWith(fontSize: 16.0),
                  ),
                ),
              );
            },
            todayDayBuilder: (context, date, _) {
              return Container(
                margin: const EdgeInsets.all(4.0),
                padding: const EdgeInsets.only(top: 5.0, left: 6.0),
                color: Colors.amber[400],
                width: 100,
                height: 100,
                child: Text(
                  '${date.day}',
                  style: TextStyle().copyWith(fontSize: 16.0),
                ),
              );
            },
            markersBuilder: (context, date, events, holidays) {
              final children = <Widget>[];
    
              if (events.isNotEmpty) {
                children.add(
                  Positioned(
                    right: 1,
                    bottom: 1,
                    child: _buildEventsMarker(date, events),
                  ),
                );
              }
    
              if (holidays.isNotEmpty) {
                children.add(
                  Positioned(
                    right: -2,
                    top: -2,
                    child: _buildHolidaysMarker(),
                  ),
                );
              }
    
              return children;
            },
          ),
          onDaySelected: (date, events) {
            _onDaySelected(date, events);
            _animationController.forward(from: 0.0);
          },
          onVisibleDaysChanged: _onVisibleDaysChanged,
        );
      }
    
      void _onVisibleDaysChanged(
          DateTime first, DateTime last, CalendarFormat format) {
        print('CALLBACK: _onVisibleDaysChanged');
      }
    
      Widget _buildEventsMarker(DateTime date, List events) {
        return AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          decoration: BoxDecoration(
            shape: BoxShape.rectangle,
            color: _calendarController.isSelected(date)
                ? Colors.brown[500]
                : _calendarController.isToday(date)
                    ? Colors.brown[300]
                    : Colors.blue[400],
          ),
          width: 16.0,
          height: 16.0,
          child: Center(
            child: Text(
              '${events.length}',
              style: TextStyle().copyWith(
                color: Colors.white,
                fontSize: 12.0,
              ),
            ),
          ),
        );
      }
    
      Widget _buildHolidaysMarker() {
        return Icon(
          Icons.add_box,
          size: 20.0,
          color: Colors.blueGrey[800],
        );
      }
    
      Widget _buildEventList() {
        return ListView(
          children: _selectedEvents
              .map((event) => Container(
                    decoration: BoxDecoration(
                      border: Border.all(width: 0.8),
                      borderRadius: BorderRadius.circular(12.0),
                    ),
                    margin:
                        const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
                    child: ListTile(
                      title: Text(event.toString()),
                      onTap: () => print('$event tapped!'),
                    ),
                  ))
              .toList(),
        );
      }
    }
    
    0 讨论(0)
  • 2021-01-23 07:34

    I think your fetch method should be like this:

      Future<List<Post>> getData() async{
      String link = baseURL + fetchTodoByDate;
      var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
    
    var fetch =  List<Data>();
    if (res.statusCode == 200 ) {
      var datesJson = json.decode(res.body);
      for(var dateJson in datesJson){
        fetch.add(Data.fromJson((dateJson)));
      }
    }
    return fetch;
    

    }

    0 讨论(0)
提交回复
热议问题