import 'dart:collection';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/date_symbol_data_local.dart';
class Event {
final String title;
const Event(this.title);
@override
String toString() => title;
}
/// Example events.
///
/// Using a [LinkedHashMap] is highly recommended if you decide to use a map.
final kEvents = LinkedHashMap>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(_kEventSource);
final _kEventSource = Map.fromIterable(List.generate(50, (index) => index),
key: (item) => DateTime.utc(kFirstDay.year, kFirstDay.month, item * 5),
value: (item) => List.generate(
item % 4 + 1, (index) => Event('Event $item | ${index + 1}')))
..addAll({
kToday: [
Event('Today\'s Event 1'),
Event('Today\'s Event 2'),
],
});
int getHashCode(DateTime key) {
return key.day * 1000000 + key.month * 10000 + key.year;
}
/// Returns a list of [DateTime] objects from [first] to [last], inclusive.
List daysInRange(DateTime first, DateTime last) {
final dayCount = last.difference(first).inDays + 1;
return List.generate(
dayCount,
(index) => DateTime.utc(first.year, first.month, first.day + index),
);
}
final kToday = DateTime.now();
final kFirstDay = DateTime(kToday.year, kToday.month - 3, kToday.day);
final kLastDay = DateTime(kToday.year, kToday.month + 3, kToday.day);
class TableMultiExample extends StatefulWidget {
const TableMultiExample({
Key? key,
this.width,
this.height,
this.event,
}) : super(key: key);
final double? width;
final double? height;
final List? event;
@override
_TableMultiExampleState createState() => _TableMultiExampleState();
}
class _TableMultiExampleState extends State {
final ValueNotifier> _selectedEvents = ValueNotifier([]);
// Using a `LinkedHashSet` is recommended due to equality comparison override
final Set _selectedDays = LinkedHashSet(
equals: isSameDay,
hashCode: getHashCode,
);
CalendarFormat _calendarFormat = CalendarFormat.month;
DateTime _focusedDay = DateTime.now();
@override
void dispose() {
_selectedEvents.dispose();
super.dispose();
}
List _getEventsForDay(DateTime day) {
// Implementation example
return kEvents[day] ?? [];
}
List _getEventsForDays(Set days) {
// Implementation example
// Note that days are in selection order (same applies to events)
return [
for (final d in days) ..._getEventsForDay(d),
];
}
void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
setState(() {
_focusedDay = focusedDay;
// Update values in a Set
if (_selectedDays.contains(selectedDay)) {
_selectedDays.remove(selectedDay);
} else {
_selectedDays.add(selectedDay);
}
});
_selectedEvents.value = _getEventsForDays(_selectedDays);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TableCalendar - Multi'),
),
body: Column(
children: [
TableCalendar(
firstDay: kFirstDay,
lastDay: kLastDay,
focusedDay: _focusedDay,
calendarFormat: _calendarFormat,
eventLoader: _getEventsForDay,
startingDayOfWeek: StartingDayOfWeek.monday,
selectedDayPredicate: (day) {
// Use values from Set to mark multiple days as selected
return _selectedDays.contains(day);
},
onDaySelected: _onDaySelected,
onFormatChanged: (format) {
if (_calendarFormat != format) {
setState(() {
_calendarFormat = format;
});
}
},
onPageChanged: (focusedDay) {
_focusedDay = focusedDay;
},
),
ElevatedButton(
child: Text('Clear selection'),
onPressed: () {
setState(() {
_selectedDays.clear();
_selectedEvents.value = [];
});
},
),
const SizedBox(height: 8.0),
Expanded(
child: ValueListenableBuilder>(
valueListenable: _selectedEvents,
builder: (context, value, _) {
return ListView.builder(
itemCount: value.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 4.0,
),
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(12.0),
),
child: ListTile(
onTap: () => print('${value[index]}'),
title: Text('${value[index]}'),
),
);
},
);
},
),
),
],
),
);
}
}