搜尋套件、儲存庫與 APP 分類

table_calendar 封面
套件詳情v3.3.0

table_calendar

高度可自訂、功能齊全的 Flutter 日曆組件。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
74.3萬
喜歡數
3320
Pub 分數
160

安裝套件

flutter pub add table_calendar

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

TableCalendar 是一個高度可自定且功能豐富的 Flutter 日曆組件,設計用於支援廣泛的使用情境,並提供大量的設定選項。它在 Android、iOS、Web、macOS、Windows 和 Linux 等主要平台皆提供乾淨、響應式的表格佈局。此套件支援事件標記、日期選擇、導航控制與動態樣式,非常適合需要互動式日曆功能的應用程式。其模組化設計讓開發者能依應用特定需求調整外觀與行為。

適用情境

  • 事件排程應用
  • 任務管理工具
  • 預訂和預約系統
  • 每日計畫應用程式
  • 日期選擇器整合
  • 自訂日曆檢視

主要特色

  • 完全可自定義的使用者介面
  • 多日期選擇模式
  • 事件強調
  • 內建導航控制項
  • 跨平台的響應式設計
  • 可擴充的事件與日期處理

適合對象

  • 開發日曆密集型應用的開發者
  • 需要跨平台日曆一致性的團隊
  • 需要高級日期互動的應用程式
  • 希望靈活視覺自訂的設計人員

使用建議

  • 可能需要額外的樣式來適應複雜佈局
  • 大資料集的效能影響
  • 進階功能的學習曲線
  • 有限的內建地區化支援
  • 依賴外部狀態管理來處理事件

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

TableCalendar

Pub Package Awesome Flutter

Highly customizable, feature-packed calendar widget for Flutter.

Image Image
TableCalendar with custom styles TableCalendar with custom builders

Features

  • Extensive, yet easy to use API
  • Preconfigured UI with customizable styling
  • Custom selective builders for unlimited UI design
  • Locale support
  • Range selection support
  • Multiple selection support
  • Dynamic events and holidays
  • Vertical autosizing - fit the content, or fill the viewport
  • Multiple calendar formats (month, two weeks, week)
  • Horizontal swipe boundaries (first day, last day)

Usage

Make sure to check out examples and API docs for more details.

Installation

Add the following line to pubspec.yaml:

dependencies:
  table_calendar: ^3.2.1
Basic setup

The complete example is available here.

TableCalendar requires you to provide firstDay, lastDay and focusedDay:

  • firstDay is the first available day for the calendar. Users will not be able to access days before it.
  • lastDay is the last available day for the calendar. Users will not be able to access days after it.
  • focusedDay is the currently targeted day. Use this property to determine which month should be currently visible.
TableCalendar(
  firstDay: DateTime.utc(2010, 10, 16),
  lastDay: DateTime.utc(2030, 3, 14),
  focusedDay: DateTime.now(),
);
Adding interactivity

You will surely notice that previously set up calendar widget isn't quite interactive - you can only swipe it horizontally, to change the currently visible month. While it may be sufficient in certain situations, you can easily bring it to life by specifying a couple of callbacks.

Adding the following code to the calendar widget will allow it to respond to user's taps, marking the tapped day as selected:

selectedDayPredicate: (day) {
  return isSameDay(_selectedDay, day);
},
onDaySelected: (selectedDay, focusedDay) {
  setState(() {
    _selectedDay = selectedDay;
    _focusedDay = focusedDay; // update `_focusedDay` here as well
  });
},

In order to dynamically update visible calendar format, add those lines to the widget:

calendarFormat: _calendarFormat,
onFormatChanged: (format) {
  setState(() {
    _calendarFormat = format;
  });
},

Those two changes will make the calendar interactive and responsive to user's input.

Updating focusedDay

Setting focusedDay to a static value means that whenever TableCalendar widget rebuilds, it will use that specific focusedDay. You can quickly test it by using hot reload: set focusedDay to DateTime.now(), swipe to next month and trigger a hot reload - the calendar will "reset" to its initial state. To prevent this from happening, you should store and update focusedDay whenever any callback exposes it.

Add this one callback to complete the basic setup:

onPageChanged: (focusedDay) {
  _focusedDay = focusedDay;
},

It is worth noting that you don't need to call setState() inside onPageChanged() callback. You should just update the stored value, so that if the widget gets rebuilt later on, it will use the proper focusedDay.

The complete example is available here. You can find other examples here.

Events

The complete example is available here.

You can supply custom events to TableCalendar widget. To do so, use eventLoader property - you will be given a DateTime object, to which you need to assign a list of events.

eventLoader: (day) {
  return _getEventsForDay(day);
},

_getEventsForDay() can be of any implementation. For example, a Map<DateTime, List<T>> can be used:

List<Event> _getEventsForDay(DateTime day) {
  return events[day] ?? [];
}

One thing worth remembering is that DateTime objects consist of both date and time parts. In many cases this time part is redundant for calendar related aspects.

If you decide to use a Map, I suggest making it a LinkedHashMap - this will allow you to override equality comparison for two DateTime objects, comparing them just by their date parts:

final events = LinkedHashMap(
  equals: isSameDay,
  hashCode: getHashCode,
)..addAll(eventSource);
Cyclic events

eventLoader allows you to easily add events that repeat in a pattern. For example, this will add an event to every Monday:

eventLoader: (day) {
  if (day.weekday == DateTime.monday) {
    return [Event('Cyclic event')];
  }

  return [];
},
Events selected on tap

Often times having a sublist of events that are selected by tapping on a day is desired. You can achieve that by using the same method you provided to eventLoader inside of onDaySelected callback:

void _onDaySelected(DateTime selectedDay, DateTime focusedDay) {
  if (!isSameDay(_selectedDay, selectedDay)) {
    setState(() {
      _focusedDay = focusedDay;
      _selectedDay = selectedDay;
      _selectedEvents = _getEventsForDay(selectedDay);
    });
  }
}

The complete example is available here.

Custom UI with CalendarBuilders

To customize the UI with your own widgets, use CalendarBuilders. Each builder can be used to selectively override the UI, allowing you to implement highly specific designs with minimal hassle.

You can return null from any builder to use the default style. For example, the following snippet will override only the Sunday's day of the week label (Sun), leaving other dow labels unchanged:

calendarBuilders: CalendarBuilders(
  dowBuilder: (context, day) {
    if (day.weekday == DateTime.sunday) {
      final text = DateFormat.E().format(day);

      return Center(
        child: Text(
          text,
          style: TextStyle(color: Colors.red),
        ),
      );
    }
  },
),
Locale

To display the calendar in desired language, use locale property. If you don't specify it, a default locale will be used.

Initialization

Before you can use a locale, you might need to initialize date formatting.

A simple way of doing it is as follows:

  • First of all, add intl package to your pubspec.yaml file
  • Then make modifications to your main():
import 'package:intl/date_symbol_data_local.dart';

void main() {
  initializeDateFormatting().then((_) => runApp(MyApp()));
}

After those two steps your app should be ready to use TableCalendar with different languages.

Specifying a language

To specify a language, simply pass it as a String code to locale property.

For example, this will make TableCalendar use Polish language:

TableCalendar(
  locale: 'pl_PL',
),
Image Image Image Image
'en_US' 'pl_PL' 'fr_FR' 'zh_CN'

Note, that if you want to change the language of FormatButton's text, you have to do this yourself. Use availableCalendarFormats property and pass the translated Strings there. Use i18n method of your choice.

You can also hide the button altogether by setting formatButtonVisible to false.

所屬分類

依賴

依賴清單 2 項

原始碼儲存庫

使用此套件的專案

所在榜單