Articles in this section
Category / Section

How to add the indicator in the month cells of the Date Range Picker (SfDateRangePicker), when the Flutter Event Calendar (SfCalendar) has an appointments?

3 mins read

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,
),

View sample in GitHub

calendarpickergif

 

 

 

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied