Highlighting dates in flutter calendar

Viewed 1579

So I've created a basic calendar using flutter's table_calendar package.

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';

 class Calendar extends StatefulWidget {
  @override
 _CalendarState createState() => _CalendarState();
 }

 class _CalendarState extends State<Calendar> {
   CalendarFormat format = CalendarFormat.month;
   DateTime selectedDay = DateTime.now();
   DateTime focusedDay = DateTime.now();

   TextEditingController _eventController = TextEditingController();


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

   @override
   Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
       title: Text("ESTech Calendar"),
       centerTitle: true,
     ),
     body: Column(
        children: [
         //defining min an max years
         TableCalendar(
            focusedDay: selectedDay,
            firstDay: DateTime(1990),
            lastDay: DateTime(2050),

          //changing calendar format
        calendarFormat: format,
        onFormatChanged: (CalendarFormat _format) {
          setState(() {
            format = _format;
          });
        },
        startingDayOfWeek: StartingDayOfWeek.monday,
        daysOfWeekVisible: true,

        //Day Changed on select
        onDaySelected: (DateTime selectDay, DateTime focusDay) {
          setState(() {
            selectedDay = selectDay;
            focusedDay = focusDay;
          });
          print(focusedDay);
        },
        selectedDayPredicate: (DateTime date) {
          return isSameDay(selectedDay, date);
        },


        //To style the Calendar
        calendarStyle: CalendarStyle(
          isTodayHighlighted: true,
          selectedDecoration: BoxDecoration(
            color: Colors.blue,
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(5.0),
          ),
          selectedTextStyle: TextStyle(color: Colors.white),
          todayDecoration: BoxDecoration(
            color: Colors.purpleAccent,
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(5.0),
          ),
          defaultDecoration: BoxDecoration(
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(5.0),
          ),
          weekendDecoration: BoxDecoration(
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(5.0),
          ),
        ),
        headerStyle: HeaderStyle(
          formatButtonVisible: true,
          titleCentered: true,
          formatButtonShowsNext: false,
          formatButtonDecoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.circular(5.0),
          ),
          formatButtonTextStyle: TextStyle(
            color: Colors.white,
          ),
        ),
      ),
    ],
  ),
);
}
}

and the out put is such, output

what I want is to input some dates using a list or some sort and I want the calendar to highlight those days like in the picture below

Expected output

Please help me achieve it.Should I use events ? if so please tell me how to !!!

2 Answers

Add a list of DateTime as parameter to your Calendar widget:

class Calendar extends StatefulWidget {
  const Calendar({
    required this.toHighlight,
    Key? key,
  }) : super(key: key);

  @override
  _CalendarState createState() => _CalendarState();

  final List<DateTime> toHighlight;
}

Inside the calendar Build, add the calendarBuilders property. Within this property you can use the defaultBuilder option to override the cell widget in specific cases:

calendarBuilders: CalendarBuilders(
              defaultBuilder: (context, day, focusedDay) {
                for (DateTime d in widget.toHighlight) {
                  if (day.day == d.day &&
                      day.month == d.month &&
                      day.year == d.year) {
                    return Container(
                      decoration: const BoxDecoration(
                        color: Colors.lightGreen,
                        borderRadius: BorderRadius.all(
                          Radius.circular(8.0),
                        ),
                      ),
                      child: Center(
                        child: Text(
                          '${day.day}',
                          style: const TextStyle(color: Colors.white),
                        ),
                      ),
                    );
                  }
                }
                return null;
              },
            ),

As you can see I've implemented a basic comparison between the cell date and the dates which sent as toHighlight parameter.

If you want your highlighted cells to maintain their new apparence even if focused or selected, you can use the prioritizedBuilder property.

Here's the Docs references:

CalendarBuilders Docs

Related