Timetable
π Customizable flutter calendar widget including day and week views
Install / Use
/learn @JonasWanke/TimetableREADME
π Customizable, animated calendar widget including day, week, and month views.
| Navigation | Animation |
| :-------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------: |
|
|
|
| Callbacks | Changing the [VisibleDateRange] |
| :------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------: |
|
|
|
Available Layouts
[MultiDateTimetable]
A Timetable widget that displays multiple consecutive days.
| Light Mode | Dark Mode |
| :---------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------: |
|
|
|
[RecurringMultiDateTimetable]
A Timetable widget that displays multiple consecutive days without their dates and without a week indicator.
| Light Mode | Dark Mode |
| :------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------: |
|
|
|
[CompactMonthTimetable]
A Timetable widget that displays [MonthWidget]s in a page view.
| Light Mode | Dark Mode |
| :------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------: |
|
|
|
Getting started
0. General Information
Timetable doesn't care about any time-zone related stuff.
All supplied DateTimes must have isUtc set to true, but the actual time zone is then ignored when displaying events.
Some date/time-related parameters also have special suffixes:
date: ADateTimewith a time of zero.month: ADateTimewith a time of zero and a day of one.timeOfDay: ADurationbetween zero and 24 hours.dayOfWeek: Anintbetween one and seven (DateTime.mondaythroughDateTime.sunday).
Timetable currently offers localizations for Chinese, English, French, German, Hungarian, Italian, Japanese, Portuguese, and Spanish.
Even if you're just supporting English in your app, you have to add Timetable's localization delegate to your MaterialApp/CupertinoApp/WidgetsApp:
MaterialApp(
localizationsDelegates: [
TimetableLocalizationsDelegate(),
// Other delegates, e.g., `GlobalMaterialLocalizations.delegate`
],
// ...
);
You want to contribute a new localization? Awesome! Please follow the steps listed in the doc comment of [
TimetableLocalizationsDelegate].
1. Define your [Event]s
Events are provided as instances of [Event].
To get you started, there's the subclass [BasicEvent], which you can instantiate directly.
If you want to be more specific, you can also implement your own class extending [Event].
β οΈ Most of Timetable's classes accept a type-parameter
E extends Event. Please set it to your chosen [Event]-subclass (e.g., [BasicEvent]) to avoid runtime exceptions.
In addition, you also need a Widget to display your events.
When using [BasicEvent], this can simply be [BasicEventWidget].
2. Create a [DateController] (optional)
Similar to a [ScrollController] or a [TabController], a [DateController] is responsible for interacting with Timetable's widgets and managing their state.
As the name suggests, you can use a [DateController] to access the currently visible dates, and also animate or jump to different days.
And by supplying a [VisibleDateRange], you can also customize how many days are visible at once and whether they, e.g., snap to weeks.
final myDateController = DateController(
// All parameters are optional and displayed with their default value.
initialDate: DateTimeTimetable.today(),
visibleRange: VisibleDateRange.week(startOfWeek: DateTime.monday),
);
Don't forget to [
dispose][DateController.dispose] your controller, e.g., in [State.dispose]!
Here are some of the available [VisibleDateRange]s:
- [
VisibleDateRange.days]: displaysvisibleDayCountconsecutive days, snapping to everyswipeRangedays (aligned toalignmentDate) in the range fromminDatetomaxDate - [
VisibleDateRange.week]: displays and snaps to whole weeks with a customizablestartOfWeekin the range fromminDatetomaxDate - [
VisibleDateRange.weekAligned]: displaysvisibleDayCountconsecutive days while snapping to whole weeks with a customizablefirstDayin the range fromminDatetomaxDateβ―ββcan be used, e.g., to display a five-day workweek
3. Create a [TimeController] (optional)
Similar to the [DateController] above, a [TimeController] is also responsible for interacting with Timetable's widgets and managing their state.
More specifically, it controls the visible time range and zoom factor in a [MultiDateTimetable] or [RecurringMultiDateTimetable].
You can also programmatically change those and, e.g., animate out to reveal the full day.
final myTimeController = TimeController(
// All parameters are optional. By default, the whole day is revealed
// initially and you can zoom in to view just a single minute.
minDuration: 15.minutes, // The closest you can zoom in.
maxDuration: 23.hours, // The farthest you can zoom out.
initialRange: TimeRange(9.hours, 17.hours),
maxRange: TimeRange(0.hours, 24.hours),
);
This example uses some of [<kbd>time</kbd>]'s extension methods on
intto create a [Duration] more concisely.
Don't forget to [
dispose][TimeController.dispose] your controller, e.g., in [State.dispose]!
4. Create your Timetable widget
The configuration for Timetable's widgets is provided via inherited widgets.
You can use a [TimetableConfig<E>] to provide all at once:
TimetableConfig<BasicEvent>(
// Required:
dateController: _dateController,
timeController: _timeController,
eventBuilder: (context, event) => BasicEventWidget(event),
child: MultiDateTimetable<BasicEvent>(),
// Optional:
eventProvider: (date) => someListOfEvents,
allDayEventBuilder: (context, event, info) =>
BasicAllDayEventWidget(event, info: info),
allDayOverflowBuilder: (date, overflowedEvents) => /* β¦ */,
callbacks: TimetableCallbacks(
// onWeekTap, onDateTap, onDateBackgroundTap, onDateTimeBackgroundTap, and
// onMultiDateHeaderOverflowTap
),
theme: TimetableThemeData(
context,
// startOfWeek: DateTime.monday,
// See the "Theming" section below for more options.
),
)
And you're done π
Theming
Timetable already supports light and dark themes out of the box, adapting to the ambient ThemeData.
You can, however, customize the styles of almost all components by providing
