Events topic
Events
This is part of the kalender documentation.
The event model, and how to attach your own data to it. For where tiles are placed on screen, see Layout. For what they look like, see Appearance.
Custom Events
KalenderEvent is not generic. Attach custom data (title, color, description, and so on) by extending KalenderEvent directly.
class Event extends KalenderEvent {
final String title;
final String? description;
final Color? color;
Event({
super.id,
required super.start,
required super.end,
required this.title,
this.description,
this.color,
super.interaction,
super.multiDayRule,
super.isAllDay,
});
// Rebuilds the fields this class adds. The calendar restores the rest.
@override
Event copyWithData({required DateTime start, required DateTime end}) {
return Event(
start: start,
end: end,
title: title,
description: description,
color: color,
);
}
// A copy method of your own. It is not an override, so it takes whatever
// parameters suit you. carryOver keeps the copy's identity and rule.
Event copyWith({DateTime? start, DateTime? end, String? title, String? description, Color? color}) {
return carryOver(
Event(
start: start ?? this.start,
end: end ?? this.end,
title: title ?? this.title,
description: description ?? this.description,
color: color ?? this.color,
),
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return super == other &&
other is Event &&
other.title == title &&
other.description == description &&
other.color == color;
}
@override
int get hashCode => Object.hash(super.hashCode, title, description, color);
}
Note
If you don't override == and hashCode, the calendar cannot detect changes to your custom fields and tiles will not update when those values change (e.g. via eventsController.updateEvent(...)). Always override both whenever you add fields to your KalenderEvent subclass.
The copy contract
The calendar calls withDateTimeRange on every drag and resize. It calls your copyWithData, then restores the id, interaction, multiDayRule and isAllDay that KalenderEvent holds, which is why copyWithData lists only your own fields. Call carryOver from a copy method of your own to get the same. A subclass with no copyWithData is flagged by the analyzer, since it is @mustBeOverridden.
Updating events
Use eventsController.updateEvent() to replace an existing event with an updated copy:
final original = eventsController.byId(someId)! as Event;
final updated = original.copyWith(title: 'Updated Title', color: Colors.red);
eventsController.updateEvent(event: original, updatedEvent: updated);
layoutEquals
Only override layoutEquals when a custom property changes the size or position of the tile, for example a flag that makes a tile render taller. It is not for content-only changes like color or title. The default implementation compares id, dateTimeRange, interaction, multiDayRule and isAllDay, which is sufficient for most cases.
Accessing custom fields in tile builders
Cast the event to your subclass:
TileComponents(
tileBuilder: (context, event, tileRange) {
final myEvent = event as Event;
return Container(
color: myEvent.color ?? Colors.blue,
child: Text(myEvent.title),
);
},
)
Returning your subclass on event creation
Return your subclass from onEventCreate in KalenderView.callbacks:
KalenderCallbacks(
onEventCreate: (event) => Event(
start: event.start,
end: event.end,
title: 'New Event',
color: Colors.blue,
),
onEventCreated: (event) => eventsController.addEvent(event),
)
Multi-day and all-day events
A MultiDayRule decides whether an event renders in the multi-day header lane or in the day timeline. The rule is set on the view configuration (see Shared options) and defaults to counting events of 24 hours or longer as multi-day.
An event that is all-day by nature rather than by duration says so directly, and no rule is consulted:
KalenderEvent(start: range.start, end: range.end, isAllDay: true)
This puts it in the header lane whatever its duration. The date range is left alone, so an app wanting midnight to midnight supplies it. isAllDay defaults to false, where the rules below apply.
A single event can override the calendar's rule:
KalenderEvent(
start: range.start,
end: range.end,
multiDayRule: const MultiDayRule.calendarDays(),
)
spansMultipleDays returns whether an event counts as multi-day, applying the same rules the calendar does:
event.spansMultipleDays(location: location, defaultRule: viewConfiguration.multiDayRule)
The event's own multiDayRule takes precedence when set. Otherwise defaultRule applies. Pass the calendar's location so that rules measuring calendar days, such as MultiDayRule.calendarDays, place midnight in the right timezone.
Classes
- DefaultEventsController Events
- The default EventsController for managing KalenderEvents.
- DefaultEventStore Events
- The default class for storing KalenderEvents.
- EventsController Events
- The EventsController is used to manage KalenderEvents.
- EventStore Events
- A class that maps KalenderEvents to dates.
- KalenderEvent Events
- Base class for events displayed in the calendar.
- MultiDayRule Events
- Decides whether an event belongs in the multi-day header lane rather than the day timeline.
Constants
- kDefaultMultiDayRule → const MultiDayRule Events
- The rule a calendar uses when nothing overrides it: 24 hours or longer.
Typedefs
-
DateToEventIds
= Map<
String, Set< EventsString> > - Maps a date key from DefaultEventStore.toKey to the ids of the events on that date.
-
EventIdToEvent
= Map<
String, KalenderEvent> Events - Maps an event id to its KalenderEvent.
-
LocationDateIdMap
= Map<
String, DateToEventIds> Events - Maps a timezone location name to its DateToEventIds.
- UpdatedEvent = (KalenderEvent, KalenderEvent) Events