How to add the indicator in the month cells of the Date Range Picker (SfDateRangePicker), when the Flutter Event Calendar (SfCalendar) has an appointments?
In the Flutter event date range picker, you can integrate the calendar and date range picker, also you can show the indicator for appointments date in date range picker using BoxPainter.
STEP 1: In initState(), set the default values needed for the calendar and date range picker.
final CalendarController _calendarController = CalendarController(); final DateRangePickerController _dateRangePickerController = DateRangePickerController(); late _AppointmentDataSource _appointmentDataSource; late List<DateTime> _specialDates; @override void initState() { _appointmentDataSource = _getCalendarDataSource(); _specialDates = <DateTime>[]; for(int i = 0; i < _appointmentDataSource.appointments!.length; i++){ _specialDates.add(_appointmentDataSource.appointments![i].startTime); } super.initState(); }
STEP 2: Create a class for month cell decoration, that is extended from the Decoration class.
class _MonthCellDecoration extends Decoration { const _MonthCellDecoration( {this.borderColor, required this.backgroundColor, required this.showIndicator, required this.indicatorColor}); final Color? borderColor; final Color backgroundColor; final bool showIndicator; final Color indicatorColor; @override BoxPainter createBoxPainter([VoidCallback? onChanged]) { return _MonthCellDecorationPainter( borderColor: borderColor, backgroundColor: backgroundColor, showIndicator: showIndicator, indicatorColor: indicatorColor); } } class _MonthCellDecorationPainter extends BoxPainter { _MonthCellDecorationPainter( {this.borderColor, required this.backgroundColor, required this.showIndicator, required this.indicatorColor}); final Color? borderColor; final Color backgroundColor; final bool showIndicator; final Color indicatorColor; @override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { final Rect bounds = offset & configuration.size!; _drawDecoration(canvas, bounds); } void _drawDecoration(Canvas canvas, Rect bounds) { final Paint paint = Paint()..color = backgroundColor; canvas.drawRRect( RRect.fromRectAndRadius(bounds, const Radius.circular(5)), paint); paint.style = PaintingStyle.stroke; paint.strokeWidth = 1; if (borderColor != null) { paint.color = borderColor!; canvas.drawRRect( RRect.fromRectAndRadius(bounds, const Radius.circular(5)), paint); } if (showIndicator) { paint.color = indicatorColor; paint.style = PaintingStyle.fill; canvas.drawCircle(Offset(bounds.right - 6, bounds.top + 6), 2.5, paint); } } }
STEP 3: Using the onViewChanged and onSelectionChanged callbacks, set the displayDate and selectedDate for the calendar and date range picker. Also, in onViewChanged callback get the start time of the appointments based on the visible dates.
void selectionChanged(DateRangePickerSelectionChangedArgs args) { SchedulerBinding.instance!.addPostFrameCallback((timeStamp) { _calendarController.displayDate = args.value; }); } void viewChanged(ViewChangedDetails viewChangedDetails) { SchedulerBinding.instance!.addPostFrameCallback((timeStamp) { _dateRangePickerController.selectedDate = viewChangedDetails.visibleDates[0]; _dateRangePickerController.displayDate = viewChangedDetails.visibleDates[0]; }); }
STEP 4: Assign those date collections to special dates property of the date range picker and decorate the appointment cell using _MonthCellDecortion like below.
child: SfDateRangePicker( selectionShape: DateRangePickerSelectionShape.rectangle, selectionColor: Colors.deepPurpleAccent, todayHighlightColor: Colors.deepPurpleAccent, controller: _dateRangePickerController, monthViewSettings: DateRangePickerMonthViewSettings( numberOfWeeksInView: 1, specialDates: _specialDates, ), onSelectionChanged: selectionChanged, monthCellStyle: DateRangePickerMonthCellStyle( specialDatesDecoration: _MonthCellDecoration( borderColor: null, backgroundColor: const Color(0xfff7f4ff), showIndicator: true, indicatorColor: Colors.orange), cellDecoration: _MonthCellDecoration( borderColor: null, backgroundColor: const Color(0xfff7f4ff), showIndicator: false, indicatorColor: Colors.orange), todayCellDecoration: _MonthCellDecoration( borderColor: null, backgroundColor: const Color(0xfff7f4ff), showIndicator: false, indicatorColor: Colors.orange), ), ), child: SfCalendar( headerHeight: 0, controller: _calendarController, viewHeaderHeight: 0, dataSource: _appointmentDataSource, onViewChanged: viewChanged, ),
|
|