如何在flutter中使用table_calendar获取一个月中的所有事件? [英] How to get all events in a month using table_calendar in flutter?

查看:389
本文介绍了如何在flutter中使用table_calendar获取一个月中的所有事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在flutter中使用table_calendar构建了一个包含用户约会的日历.在当前代码中,我只能返回用户的所有约会.现在,我试图仅在同一个月内获取所有约会,并将其显示在日历下方.也就是说,当我在日历上交换月份时,应该查看我当前正在查看的月份内的约会列表.

当前,我正在从后端获取用户的所有约会记录.为了实现我的目标,哪种方式会更容易:

通过使用当月第一天的日期信息定义更改月份按钮",并使用它来选择后端的相应数据

OR

是否仍在检索所有约会记录并以某种方式在前端对其进行过滤?

有人可以帮助我以特定的解决方案实现我的目标吗?

(如下面我当前的输出所示,当我在10月的时候,我仍然看到6月的约会).

完整代码

  import'package:flutter/material.dart';导入'package:table_calendar/table_calendar.dart';导入'package:http/http.dart'为http;导入'dart:convert';导入'package:intl/intl.dart';列表<约会>subscriptionFromJson(String str)=>列出<约会" .from(json.decode(str).map((x)=> Appointment.fromJson(x)));字符串约会ToJson(列表< Appointment>数据)=>json.encode(List< dynamic> .from(data.map((x)=> x.toJson()))));班级预约{约定({这个日期this.dateChange,this.dateCreate,这个细节这个持续时间,this.id,这个笔记,这个状态这个标题这个.uid,});DateTime日期;DateTime dateChange;DateTime dateCreate;字符串细节;int持续时间;字符串ID;弦音;字符串状态;字符串标题;字符串uid;factory Appointment.fromJson(Map< String,dynamic> json)=>约定(日期:DateTime.parse(json ["date"]]),dateChange:DateTime.parse(json ["date_change"]]),dateCreate:DateTime.parse(json [" date_create"]]),详细信息:json ["detail"],持续时间:json ["duration"],id:json ["id"],注意:json ["note"],状态:json ["status"],标题:json ["title"],uid:json ["uid"],);Map< String,dynamic>toJson()=>{"date":date.toIso8601String(),"date_change":dateChange.toIso8601String(),"date_create":dateCreate.toIso8601String(),详细信息":详细信息,持续时间":持续时间,"id":id,注释":注释,状态":状态,"title":标题,"uid":uid,};}类约会扩展了StatefulWidget {@override_AppointmentsState createState()=>_AppointmentsState();}类_AppointmentsState扩展了State< Appointments>与TickerProviderStateMixin {var _calendarController;Map< DateTime,List>_events;列表<约会>_samemonthevents = List<约会>();AnimationController _animationController;DateTime当前= DateTime.now();@override无效的initState(){super.initState();_events = Map< DateTime,List>();_calendarController = CalendarController();getSameMonthAppointments();_animationController = AnimationController(vsync:这个,duration:const Duration(毫秒:400),);_animationController.forward();}@override无效dispose(){_calendarController.dispose();super.dispose();}getSameMonthAppointments()异步{字符串jsonString ='''[{日期":"2020-09-01T11:15:00Z"," date_change" ;:" 2018-05-14T10:17:40Z" ;," date_create" ;:" 2018-05-14T10:17:40Z" ;,细节":插入Inflisaport",持续时间":15"id":"2"," note":"期待与您见面!保重","status":"CONFIRMED","title":私人医院","uid":"1"},{日期":"2020-09-22T01:15:00Z"," date_change" ;:" 2018-05-14T10:17:40Z" ;," date_create" ;:" 2018-05-14T10:17:40Z" ;,细节":插入Inflisaport",持续时间":15"id":"2"," note":"期待与您见面!保重","status":"CONFIRMED","title":私人医院","uid":"1"},{日期":"2020-10-01T07:15:00Z"," date_change" ;:" 2018-05-14T10:17:40Z" ;," date_create" ;:" 2018-05-14T10:17:40Z" ;,细节":插入Inflisaport",持续时间":15"id":"2"," note":"期待与您见面!保重","status":"CONFIRMED","title":私人医院","uid":"1"},{日期":"2020-10-22T09:15:00Z"," date_change" ;:" 2018-05-14T10:17:40Z" ;," date_create" ;:" 2018-05-14T10:17:40Z" ;,细节":插入Inflisaport",持续时间":15"id":"2"," note":"期待与您见面!保重","status":"CONFIRMED","title":私人医院","uid":"1"},{日期":"2020-10-30T10:15:00Z"," date_change" ;:" 2018-05-14T10:17:40Z" ;," date_create" ;:" 2018-05-14T10:17:40Z" ;,细节":插入Inflisaport",持续时间":15"id":"2"," note":"期待与您见面!保重","status":"CONFIRMED","title":私人医院","uid":"1"}]''';http.Response响应= http.Response(jsonString,200);如果(response.statusCode == 200){_samemonthevents = subscriptionFromJson(response.body);}}无效_onVisibleDaysChanged(日期时间在前,日期时间在后,CalendarFormat格式){setState((){当前=首先;});print('CALLBACK:_onVisibleDaysChanged first $ {first.toIso8601String()}');}@override窗口小部件build(BuildContext context){返回脚手架(appBar:PreferredSize(preferredSize:Size.fromHeight(60.0),子:AppBar(领先:IconButton(图标:Icon(Icons.arrow_back),颜色:黑色.onPressed:(){setState((){});/* Navigator.push(上下文,MaterialPageRoute(builder:(context)=> MainPage())); */}),centerTitle:正确,标题:Text("Appointment",样式:TextStyle(color:Colors.black)),backgroundColor:Colors.white,亮度:Brightness.light,automaticImplyLeading:否,//backgroundColor:Color(0x44000000),海拔:0.5,动作:< Widget> [IconButton(颜色:黑色.图标:Icon(Icons.list),onPressed:(){setState((){});/* Navigator.push(语境,MaterialPageRoute(生成器:(上下文)=>AppointmentList())); */},)],),),正文:Builder(builder:(BuildContext context){return Column(children:< Widget> [_buildTableCalendarWithBuilders(),const SizedBox(高度:8.0),const SizedBox(高度:8.0),//_ buildEventList()//_ buildsameMonthEventList()Expanded(child:_buildsameMonthEventList()),]);}));}//更高级的TableCalendar配置(使用构建器和样式)小部件_buildTableCalendarWithBuilders(){返回TableCalendar(calendarController:_calendarController,事件:_events,//假期:_holidays,initialCalendarFormat:CalendarFormat.month,formatAnimation:FormatAnimation.slide,startingDayOfWeek:StartingDayOfWeek.sunday,availableGestures:AvailableGestures.all,availableCalendarFormats:const {CalendarFormat.month:''},calendarStyle:CalendarStyle(outsideDaysVisible:false,weekendStyle:TextStyle().copyWith(颜色:Colors.blue [800]),holidayStyle:TextStyle().copyWith(颜色:Colors.blue [800]),),daysOfWeekStyle:DaysOfWeekStyle(weekendStyle:TextStyle().copyWith(颜色:Colors.blue [600]),),headerStyle:HeaderStyle(centerHeaderTitle:正确,formatButtonVisible:否,),建设者:CalendarBuilders(selectedDayBuilder :(上下文,日期,_){返回FadeTransition(透明度:Tween(开始:0.0,结束:1.0).animate(_animationController),子代:集装箱(边距:const EdgeInsets.all(4.0),对齐方式:Alignment.center,装饰:BoxDecoration(颜色:Colors.blue [300],borderRadius:BorderRadius.circular(36.0),border:Border.all(width:2,color:Colors.blue [300])),子代:文字("$ {date.day}",样式:TextStyle().copyWith(fontSize:20.0,颜色:黑色.fontWeight:FontWeight.bold),),),);},todayDayBuilder :(上下文,日期,_){返回容器(边距:const EdgeInsets.all(4.0),对齐方式:Alignment.center,装饰:BoxDecoration(颜色:Colors.white,borderRadius:BorderRadius.circular(36.0),border:Border.all(width:2,color:Colors.white)),子代:文字("$ {date.day}",样式:TextStyle().copyWith(fontSize:20.0,颜色:黑色.fontWeight:FontWeight.bold),),);},markersBuilder :(上下文,日期,事件,假期){最后的孩子=< Widget> [];如果(events.isNotEmpty){children.add(定位(子代:_buildEventsMarker(date,events),),);}如果(holidays.isNotEmpty){children.add(定位(右:-2,上:-2,子代:_buildHolidaysMarker(),),);}归还孩子;},),onVisibleDaysChanged:_onVisibleDaysChanged,);}小部件_buildEventsMarker(DateTime日期,列出事件){返回AnimatedContainer(duration:const Duration(毫秒:300),边距:const EdgeInsets.all(4.0),对齐方式:Alignment.center,装饰:BoxDecoration(borderRadius:BorderRadius.circular(36.0),border:Border.all(width:2,color:Colors.blue [300])),);}小部件_buildHolidaysMarker(){返回图标(Icons.add_box,大小:20.0,颜色:Colors.blueGrey [800],);}小部件_buildsameMonthEventList(){var _samemontheventsFilter = _samemonthevents.where((element)=>element.date.year == current.year&&element.date.month == current.month);返回脚手架(appBar:PreferredSize(preferredSize:Size.fromHeight(22.0),子:AppBar(centerTitle:正确,标题:文本(本月的约会",样式:TextStyle(颜色:Colors.black,字体大小:18)),backgroundColor:Colors.yellow [200],亮度:Brightness.light,automaticImplyLeading:否,//backgroundColor:Color(0x44000000),海拔:0.5,),),正文:(_samemontheventsFilter.length == 0)?文字(本月没有约会记录!",textAlign:TextAlign.center,样式:TextStyle(颜色:Colors.black,fontSize:16)): 列表显示(子代:_samemontheventsFilter.map((event)=> Container(装饰:BoxDecoration(border:Border.all(width:0.8),borderRadius:BorderRadius.circular(12.0),),保证金:const EdgeInsets.symmetric(水平:8.0,垂直:4.0),子:(活动是约会)?ListTile(领先:SizedBox(宽度:90,child:Column(children:< Widget> [//显示工作日,工作日,工作日和工作日文本(DateFormat('EE').format(event.date)+''DateFormat.MMMd().format(event.date),样式:TextStyle(颜色:Colors.blue.withOpacity(1.0),fontWeight:FontWeight.bold,)),//显示预约的开始时间文本(DateFormat.jm().format(event.date),textAlign:TextAlign.center,溢出:TextOverflow.ellipsis,样式:TextStyle(fontWeight:FontWeight.bold,高度:1.5,)),//显示预约的结束时间文本(DateFormat.jm().format(event.date.add(期间(分钟:event.duration?0))),样式:TextStyle(颜色:Colors.black.withOpacity(0.6)),),]),),//Text(DateFormat.Hm().format(event.date)),//DateFormat.Hm().format(现在)标题:文本(event.title),尾随:event.status =='UNCONFIRMED'?列(子代:< Widget> [//event.status=='CONFIRMED'吗?图标(图标错误,颜色:Colors.pink,//大小:25.0,语义标签:'未确认的约会'),//:容器(宽度:0,高度:0),图标(Icons.arrow_right),]):图标(Icons.arrow_right),onTap:(){setState((){});/* Navigator.push(语境,MaterialPageRoute(生成器:(上下文)=>AppointmentDetail(event))); */},): 无效的)).toList()));}}void main(){runApp(MyApp());}MyApp类扩展了StatelessWidget {@override窗口小部件build(BuildContext context){返回MaterialApp(标题:"Flutter演示",主题:ThemeData(primarySwatch:Colors.blue,visualDensity:VisualDensity.adaptivePlatformDensity,),家:约会(),);}} 

I have built a calendar with user's appointments using table_calendar in flutter. In my current code, I can only return all appointments of the user. Now, I am trying to fetch all appointments within a same month only and display them below the calendar. That is to say, when I swap the month on the calendar, I should only see a list of appointments within the month I am currently looking at.

Currently, I am fetching all appointment records of the user from backend. To achieve my goal, which way will be easier:

by defining the 'change month button' with date info of the first day of that month and using it to select corresponding data in backend

OR

still retrieving all appointment records and filter them in frontend somehow?

Can anyone please help me achieving my goal with specific solution?

(As shown in my current output below, while I am at October, I am still seeing the appointment in June). Current Output

Frontend code:

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:frontend/util/authentication.dart';
import 'package:frontend/util/serverDetails.dart';
import 'package:http/http.dart' as http;
import 'package:frontend/components/appointment.dart';
import 'package:frontend/screens/appointmentdetail.dart';
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:frontend/main.dart';
import 'package:frontend/screens/appointmentlist.dart';

class Appointments extends StatefulWidget {
  @override
  _AppointmentsState createState() => _AppointmentsState();
}

class _AppointmentsState extends State<Appointments>
    with TickerProviderStateMixin {
  var _calendarController;
  Map<DateTime, List> _events;
  List<Appointment> _samemonthevents = List<Appointment>();
  AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _events = Map<DateTime, List>();
    _calendarController = CalendarController();

    getSameMonthAppointments();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );
    _animationController.forward();
  }

  @override
  void dispose() {
    _calendarController.dispose();
    super.dispose();
  }

  getSameMonthAppointments() async {
    String currentToken = await Authentication.getCurrentToken();
    print(currentToken);
    if (currentToken == null) {
      print('bouncing');
      Authentication.bounceUser(context);
    } else {
      String auth = "Bearer " + currentToken;
      String url = ServerDetails.ip +
          ':' +
          ServerDetails.port +
          ServerDetails.api +
          'me/appointments';
      print(url);
      Map<String, String> headers = {"Authorization": auth};
      print(headers);
      var jsonResponse = null;
      var response = await http.get(url, headers: headers);
      print(response.body);
      if (response.statusCode == 200) {
        print("200" + response.body);
        jsonResponse = json.decode(response.body);
        if (jsonResponse != null) {
          setState(() {
            for (var doc in jsonResponse) {
              _samemonthevents.add(Appointment.fromJson(doc));
            }
          });
        }
      } else {
        print(response.body);
      }
    }
  }

  void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    print('CALLBACK: _onVisibleDaysChanged');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(60.0),
          child: AppBar(
            leading: new IconButton(
                icon: new Icon(Icons.arrow_back),
                color: Colors.black,
                onPressed: () {
                  setState(() {});
                  Navigator.push(context,
                      MaterialPageRoute(builder: (context) => MainPage()));
                }),
            centerTitle: true,
            title: Text("Appointment", style: TextStyle(color: Colors.black)),
            backgroundColor: Colors.white,
            brightness: Brightness.light,
            automaticallyImplyLeading: false,
//          backgroundColor: Color(0x44000000),
            elevation: 0.5,
            actions: <Widget>[
              IconButton(
                color: Colors.black,
                icon: Icon(Icons.list),
                onPressed: () {
                  setState(() {});
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => AppointmentList()));
                },
              )
            ],
          ),
        ),
        body: new Builder(builder: (BuildContext context) {
          return new Column(children: <Widget>[
            _buildTableCalendarWithBuilders(),
            const SizedBox(height: 8.0),
            const SizedBox(height: 8.0),
            //_buildEventList()
            //_buildsameMonthEventList()
            Expanded(child: _buildsameMonthEventList()),
          ]);
        }));
  }

  // More advanced TableCalendar configuration (using Builders & Styles)
  Widget _buildTableCalendarWithBuilders() {
    return TableCalendar(
      calendarController: _calendarController,
      events: _events,
      //holidays: _holidays,
      initialCalendarFormat: CalendarFormat.month,
      formatAnimation: FormatAnimation.slide,
      startingDayOfWeek: StartingDayOfWeek.sunday,
      availableGestures: AvailableGestures.all,
      availableCalendarFormats: const {CalendarFormat.month: ''},
      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),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: Colors.blue[300],
                  borderRadius: BorderRadius.circular(36.0),
                  border: Border.all(width: 2, color: Colors.blue[300])),
              child: Text(
                '${date.day}',
                style: TextStyle().copyWith(
                    fontSize: 20.0,
                    color: Colors.black,
                    fontWeight: FontWeight.bold),
              ),
            ),
          );
        },
        todayDayBuilder: (context, date, _) {
          return Container(
            margin: const EdgeInsets.all(4.0),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(36.0),
                border: Border.all(width: 2, color: Colors.white)),
            child: Text(
              '${date.day}',
              style: TextStyle().copyWith(
                  fontSize: 20.0,
                  color: Colors.black,
                  fontWeight: FontWeight.bold),
            ),
          );
        },
        markersBuilder: (context, date, events, holidays) {
          final children = <Widget>[];

          if (events.isNotEmpty) {
            children.add(
              Positioned(
                child: _buildEventsMarker(date, events),
              ),
            );
          }

          if (holidays.isNotEmpty) {
            children.add(
              Positioned(
                right: -2,
                top: -2,
                child: _buildHolidaysMarker(),
              ),
            );
          }

          return children;
        },
      ),
      onVisibleDaysChanged: _onVisibleDaysChanged,
    );
  }

  Widget _buildEventsMarker(DateTime date, List events) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      margin: const EdgeInsets.all(4.0),
      alignment: Alignment.center,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(36.0),
          border: Border.all(width: 2, color: Colors.blue[300])),
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildsameMonthEventList() {
    return Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(22.0),
          child: AppBar(
            centerTitle: true,
            title: Text("Appointments of Current Month",
                style: TextStyle(color: Colors.black, fontSize: 18)),
            backgroundColor: Colors.yellow[200],
            brightness: Brightness.light,
            automaticallyImplyLeading: false,
//          backgroundColor: Color(0x44000000),
            elevation: 0.5,
          ),
        ),
        body: (_samemonthevents.length == 0)
            ? Text("No appointment record in current month!",
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.black, fontSize: 16))
            : ListView(
                children: _samemonthevents
                    .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: (event is Appointment)
                            ? ListTile(
                                leading: Column(children: <Widget>[
                                  //Show Weekday, Month and day of Appiontment
                                  Text(
                                      DateFormat('EE').format(event.date) +
                                          '  ' +
                                          DateFormat.MMMd().format(event.date),
                                      style: TextStyle(
                                        color: Colors.blue.withOpacity(1.0),
                                        fontWeight: FontWeight.bold,
                                      )),
                                  //Show Start Time of Appointment
                                  Text(DateFormat.jm().format(event.date),
                                      textAlign: TextAlign.center,
                                      overflow: TextOverflow.ellipsis,
                                      style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        height: 1.5,
                                      )),
                                  //Show End Time of Appointment
                                  Text(
                                    DateFormat.jm().format(event.date.add(
                                        Duration(
                                            minutes: event.duration ?? 0))),
                                    style: TextStyle(
                                        color: Colors.black.withOpacity(0.6)),
                                  ),
                                ]), //Text(DateFormat.Hm().format(event.date)),//DateFormat.Hm().format(now)
                                title: Text(event.title),
                                trailing: event.status == 'UNCONFIRMED'
                                    ? Column(children: <Widget>[
                                        //event.status=='CONFIRMED' ?
                                        Icon(Icons.error,
                                            color: Colors.pink,
                                            //size:25.0,
                                            semanticLabel:
                                                'Unconfirmed Appointment'), //:Container(width:0,height:0),
                                        Icon(Icons.arrow_right),
                                      ])
                                    : Icon(Icons.arrow_right),
                                onTap: () {
                                  setState(() {});
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              AppointmentDetail(event)));
                                },
                              )
                            : null))
                    .toList()));
  }
}

Backend Code:

AppointmentAPI.java

    @GET
    @Path("me/appointments")
    @Secured(UserRole.PATIENT)
    @JSONP(queryParam = "callback")
    @Produces(MediaType.APPLICATION_JSON)
    public Response listMyAppointments(
            @Context SecurityContext sc,
            @QueryParam("since") String since,
            @QueryParam("until") String until,
            @QueryParam("is_confirmed") Boolean is_confirmed) {

        String uid = sc.getUserPrincipal().getName();
        List<Appointment> results = retrieveUserAppointments(uid, since, until, is_confirmed);

        return Response.ok(results).build();
    }

AppointmentMapper.java

    List<Appointment> getAppointmentsByUserId(
            @Param("uid")  String uid,
            @Param("since")  String since,
            @Param("until")  String until,
            @Param("status") AppointmentStatus status);

AppointmentMapper.xml

<mapper namespace="com.sec.db.AppointmentMapper">
    <select id="getAppointmentById" parameterType="String" resultType="com.sec.entity.Appointment">
        SELECT * FROM Appointment WHERE id= #{id}
    </select>

    <select id="getAppointmentsByUserId" resultType="com.sec.entity.Appointment">
        SELECT *
        FROM Appointment
        WHERE uid= #{uid}
        <choose>
            <when test="since != null and until != null">
                AND date BETWEEN #{since} AND #{until}
            </when>
            <when test="since != null and until == null">
                AND date > #{since}
            </when>
            <when test="since == null and until != null">
                <![CDATA[
                AND date < #{until}
                ]]>
            </when>
        </choose>
        <choose>
            <when test="status == null">
                AND status != 'CANCELLED'
            </when>
            <otherwise>
                AND status = #{status}
            </otherwise>
        </choose>
    </select>

Json Response Example:

### Response

    Status: 200 OK

```JSON
[
  {
    "date": "2020-06-22T14:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  }
]

解决方案

You can copy paste run full code below
Step 1: You can use a variable current to control current year/month
Step 2: You can in _onVisibleDaysChanged, call setState and set current
Step 3: In _buildsameMonthEventList, do filter with every events year/month with current's year/month

code snippet

DateTime current = DateTime.now();
...
void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    setState(() {
      current = first;
    });
    print('CALLBACK: _onVisibleDaysChanged first ${first.toIso8601String()}');
  }
...  
 Widget _buildsameMonthEventList() {
    var _samemontheventsFilter = _samemonthevents.where((element) =>
        element.date.year == current.year &&
        element.date.month == current.month);

    return Scaffold(
        ...
        body: (_samemontheventsFilter.length == 0)
            ? Text("No appointment record in current month!",
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.black, fontSize: 16))
            : ListView(
                children: _samemontheventsFilter
                    .map((event) => Container(  

working demo

full code

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:intl/intl.dart';

List<Appointment> appointmentFromJson(String str) => List<Appointment>.from(
    json.decode(str).map((x) => Appointment.fromJson(x)));

String appointmentToJson(List<Appointment> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Appointment {
  Appointment({
    this.date,
    this.dateChange,
    this.dateCreate,
    this.detail,
    this.duration,
    this.id,
    this.note,
    this.status,
    this.title,
    this.uid,
  });

  DateTime date;
  DateTime dateChange;
  DateTime dateCreate;
  String detail;
  int duration;
  String id;
  String note;
  String status;
  String title;
  String uid;

  factory Appointment.fromJson(Map<String, dynamic> json) => Appointment(
        date: DateTime.parse(json["date"]),
        dateChange: DateTime.parse(json["date_change"]),
        dateCreate: DateTime.parse(json["date_create"]),
        detail: json["detail"],
        duration: json["duration"],
        id: json["id"],
        note: json["note"],
        status: json["status"],
        title: json["title"],
        uid: json["uid"],
      );

  Map<String, dynamic> toJson() => {
        "date": date.toIso8601String(),
        "date_change": dateChange.toIso8601String(),
        "date_create": dateCreate.toIso8601String(),
        "detail": detail,
        "duration": duration,
        "id": id,
        "note": note,
        "status": status,
        "title": title,
        "uid": uid,
      };
}

class Appointments extends StatefulWidget {
  @override
  _AppointmentsState createState() => _AppointmentsState();
}

class _AppointmentsState extends State<Appointments>
    with TickerProviderStateMixin {
  var _calendarController;
  Map<DateTime, List> _events;
  List<Appointment> _samemonthevents = List<Appointment>();
  AnimationController _animationController;
  DateTime current = DateTime.now();

  @override
  void initState() {
    super.initState();
    _events = Map<DateTime, List>();
    _calendarController = CalendarController();

    getSameMonthAppointments();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );
    _animationController.forward();
  }

  @override
  void dispose() {
    _calendarController.dispose();
    super.dispose();
  }

  getSameMonthAppointments() async {
    String jsonString = '''
    [
  {
    "date": "2020-09-01T11:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  },
  {
    "date": "2020-09-22T01:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  },
  {
    "date": "2020-10-01T07:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  },
  {
    "date": "2020-10-22T09:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  },
  {
    "date": "2020-10-30T10:15:00Z",
    "date_change": "2018-05-14T10:17:40Z",
    "date_create": "2018-05-14T10:17:40Z",
    "detail": "Inflisaport Insertion",
    "duration": 15,
    "id": "2",
    "note": "Looking forward to see you! Take care",
    "status": "CONFIRMED",
    "title": "Private Hospital",
    "uid": "1"
  }
]
    ''';

    http.Response response = http.Response(jsonString, 200);
    if (response.statusCode == 200) {
      _samemonthevents = appointmentFromJson(response.body);
    }
  }

  void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    setState(() {
      current = first;
    });
    print('CALLBACK: _onVisibleDaysChanged first ${first.toIso8601String()}');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(60.0),
          child: AppBar(
            leading: IconButton(
                icon: Icon(Icons.arrow_back),
                color: Colors.black,
                onPressed: () {
                  setState(() {});
                  /* Navigator.push(context,
                      MaterialPageRoute(builder: (context) => MainPage()));*/
                }),
            centerTitle: true,
            title: Text("Appointment", style: TextStyle(color: Colors.black)),
            backgroundColor: Colors.white,
            brightness: Brightness.light,
            automaticallyImplyLeading: false,
//          backgroundColor: Color(0x44000000),
            elevation: 0.5,
            actions: <Widget>[
              IconButton(
                color: Colors.black,
                icon: Icon(Icons.list),
                onPressed: () {
                  setState(() {});
                  /* Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => AppointmentList()));*/
                },
              )
            ],
          ),
        ),
        body: Builder(builder: (BuildContext context) {
          return Column(children: <Widget>[
            _buildTableCalendarWithBuilders(),
            const SizedBox(height: 8.0),
            const SizedBox(height: 8.0),
            //_buildEventList()
            //_buildsameMonthEventList()
            Expanded(child: _buildsameMonthEventList()),
          ]);
        }));
  }

  // More advanced TableCalendar configuration (using Builders & Styles)
  Widget _buildTableCalendarWithBuilders() {
    return TableCalendar(
      calendarController: _calendarController,
      events: _events,
      //holidays: _holidays,
      initialCalendarFormat: CalendarFormat.month,
      formatAnimation: FormatAnimation.slide,
      startingDayOfWeek: StartingDayOfWeek.sunday,
      availableGestures: AvailableGestures.all,
      availableCalendarFormats: const {CalendarFormat.month: ''},
      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),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: Colors.blue[300],
                  borderRadius: BorderRadius.circular(36.0),
                  border: Border.all(width: 2, color: Colors.blue[300])),
              child: Text(
                '${date.day}',
                style: TextStyle().copyWith(
                    fontSize: 20.0,
                    color: Colors.black,
                    fontWeight: FontWeight.bold),
              ),
            ),
          );
        },
        todayDayBuilder: (context, date, _) {
          return Container(
            margin: const EdgeInsets.all(4.0),
            alignment: Alignment.center,
            decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(36.0),
                border: Border.all(width: 2, color: Colors.white)),
            child: Text(
              '${date.day}',
              style: TextStyle().copyWith(
                  fontSize: 20.0,
                  color: Colors.black,
                  fontWeight: FontWeight.bold),
            ),
          );
        },
        markersBuilder: (context, date, events, holidays) {
          final children = <Widget>[];

          if (events.isNotEmpty) {
            children.add(
              Positioned(
                child: _buildEventsMarker(date, events),
              ),
            );
          }

          if (holidays.isNotEmpty) {
            children.add(
              Positioned(
                right: -2,
                top: -2,
                child: _buildHolidaysMarker(),
              ),
            );
          }

          return children;
        },
      ),
      onVisibleDaysChanged: _onVisibleDaysChanged,
    );
  }

  Widget _buildEventsMarker(DateTime date, List events) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      margin: const EdgeInsets.all(4.0),
      alignment: Alignment.center,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(36.0),
          border: Border.all(width: 2, color: Colors.blue[300])),
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildsameMonthEventList() {
    var _samemontheventsFilter = _samemonthevents.where((element) =>
        element.date.year == current.year &&
        element.date.month == current.month);

    return Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(22.0),
          child: AppBar(
            centerTitle: true,
            title: Text("Appointments of Current Month",
                style: TextStyle(color: Colors.black, fontSize: 18)),
            backgroundColor: Colors.yellow[200],
            brightness: Brightness.light,
            automaticallyImplyLeading: false,
//          backgroundColor: Color(0x44000000),
            elevation: 0.5,
          ),
        ),
        body: (_samemontheventsFilter.length == 0)
            ? Text("No appointment record in current month!",
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.black, fontSize: 16))
            : ListView(
                children: _samemontheventsFilter
                    .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: (event is Appointment)
                            ? ListTile(
                                leading: SizedBox(
                                  width: 90,
                                  child: Column(children: <Widget>[
                                    //Show Weekday, Month and day of Appiontment
                                    Text(
                                        DateFormat('EE').format(event.date) +
                                            '  ' +
                                            DateFormat.MMMd().format(event.date),
                                        style: TextStyle(
                                          color: Colors.blue.withOpacity(1.0),
                                          fontWeight: FontWeight.bold,
                                        )),
                                    //Show Start Time of Appointment
                                    Text(DateFormat.jm().format(event.date),
                                        textAlign: TextAlign.center,
                                        overflow: TextOverflow.ellipsis,
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          height: 1.5,
                                        )),
                                    //Show End Time of Appointment
                                    Text(
                                      DateFormat.jm().format(event.date.add(
                                          Duration(
                                              minutes: event.duration ?? 0))),
                                      style: TextStyle(
                                          color: Colors.black.withOpacity(0.6)),
                                    ),
                                  ]),
                                ), //Text(DateFormat.Hm().format(event.date)),//DateFormat.Hm().format(now)
                                title: Text(event.title),
                                trailing: event.status == 'UNCONFIRMED'
                                    ? Column(children: <Widget>[
                                        //event.status=='CONFIRMED' ?
                                        Icon(Icons.error,
                                            color: Colors.pink,
                                            //size:25.0,
                                            semanticLabel:
                                                'Unconfirmed Appointment'), //:Container(width:0,height:0),
                                        Icon(Icons.arrow_right),
                                      ])
                                    : Icon(Icons.arrow_right),
                                onTap: () {
                                  setState(() {});
                                  /* Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) =>
                                AppointmentDetail(event)));*/
                                },
                              )
                            : null))
                    .toList()));
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Appointments(),
    );
  }
}

这篇关于如何在flutter中使用table_calendar获取一个月中的所有事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆