How to add indicator in the month cells of Flutter SfDateRangePicker?
In the Flutter event date range picker, you can integrate the calendar and date range picker functionality while also displaying indicators for appointment dates using BoxPainter.
STEP 1: In the initState(), set up 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 extends 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: Use 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 the date collections to the special dates property of the date range picker and decorate the appointment cells using the custom _MonthCellDecoration.
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, ),
|
|