Dev/Flutter

Flutter - Calendar / SfCalendar / Syncfusion / 캘린더

healthyryu 2022. 1. 7. 10:55

Flutter 에도 많은 라이브러리들이 존재한다. 그리고 잘 만들어져 있고 커스텀하기 좋은 Calendar 라이브러리가 Syncfusion 에서 만든 Calendar 입니다.

 

- Syncfusion Flutter Calendar 라이브러리 링크

 

✔️ 데이터 리로딩 이슈

SfCalendar 를 사용할때, 데이터를 셋팅해주는 부분이 있다. 그런데 여기서 나는 API 에서 데이터를 다시 받아와서 캘린더에 뿌려줘야하는데 종종 데이터를 제대로 뿌려주지 못하는 이슈가 발생했는데, API 에서는 데이터를 잘 내려받지만 캘린더에 표시가 됐다가 안됐다가를 반복해서 이래저래 시도해보다가 검색해서 데이터를 다시 리로딩하는 방법을 찾고 수정했습니다.

- 리로딩 이슈 해결 방법 링크

 

❗ 처음 시도한 방식

1. 아래와 같이 UI 적으로 SfCalendar 를 셋팅

List<String> _list = List.empty(growable: true);
...

Widget _calendar() {
  return SfCalendar(
    view: CalendarView.month,
    initialSelectedDate: DateTime.now(),
    dataSource: ReportCalendarDataSource(_list),
    monthCellBuilder: (BuildContext context, MonthCellDetails details) { ... }
    ...
  );
}

2. 데이터 갱신

loadMedicineCalendar((list) {
  setState(() {
    _list = list;
  });
}

참고로 저의 ReportCalendarDataSource 는 Calendar 에 데이터를 넣어줘야하기 때문에 당연히 CalendarDataSource 를 상속받은 class 입니다.

class ReportCalendarDataSource extends CalendarDataSource {
  ReportCalendarDataSource(List<DateValueItem> source) {
    appointments = source;
  }

  @override
  DateTime getStartTime(int index) {
    return DateTime.parse(appointments![index].date);
  }

  @override
  DateTime getEndTime(int index) {
    return DateTime.parse(appointments![index].date);
  }

  @override
  String getSubject(int index) {
    return appointments![index].value.toString();
  }

  @override
  Color getColor(int index) {
    return const Color(0x00000000);
  }

  @override
  bool isAllDay(int index) {
    return true;
  }
}

위와 같이 일반적인 방식으로 리스트를 갱신해주면 데이터 갱신이 원하는데로 잘 되지가 않습니다.

 

❗ 링크를 참조해서 수정한 방법

ReportCalendarDataSource? _dataSource;
List<String> _calendarList = List.empty(growable: true);
...

@override
  void initState() {
    super.initState();
    _dataSource = ReportCalendarDataSource(_calendarList);
    ...
  }
  
...

Widget _calendar() {
  return
    SfCalendar(
      view: CalendarView.month,
      initialSelectedDate: DateTime.now()
      dataSource: _dataSource,
      ...
   );
}

...

loadMedicineCalendar((list) {
  _calendarList = list;
  _dataSource!.appointments?.clear();
  _dataSource!.appointments?.addAll(_calendarList);
  _dataSource!.notifyListeners(CalendarDataSourceAction.reset, list);
  _dataSource = ReportCalendarDataSource(list);
  setState((){ });
}
반응형