패키지, 저장소 및 앱 카테고리 검색

timetable 표지
패키지 상세v0.2.9

timetable

📅 사용자 정의 가능하고 애니메이션 효과가 있는 캘린더 위젯 (일/주 보기 포함)

30일 다운로드
413
좋아요
220
Pub 점수
40

패키지 설치

flutter pub add timetable

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

타임테이블 패키지는 플러터용 사용자 정의가 가능한 애니메이션 캘린더 위젯을 제공하며, 일간 및 주간 보기 모두를 지원합니다. 부드러운 애니메이션과 직관적인 탐색 기능을 갖추고 있어 사용자가 일정과 이벤트를 상호작용 방식으로 시각화할 수 있도록 합니다. jonaswanke.dev에서 개발한 이 패키지는 작업 관리자, 예약 스케줄러 또는 수업 시간표와 같은 시간 기반 계획이 필요한 앱에 적합합니다. 플러터 프로젝트에 원활하게 통합되며, 앱 디자인에 맞게 유연한 스타일링 옵션을 제공합니다. 소스 코드는 투명성과 기여를 위해 GitHub에서 공개되어 있습니다.

사용 사례

  • 스케줄링 애플리케이션
  • 작업 및 이벤트 관리
  • 교육 시간표
  • 예약 예약 시스템
  • 일일 계획 인터페이스

주요 기능

  • 뷰 간의 애니메이션 전환
  • 일 및 주 보기 지원
  • 사용자 정의 가능한 UI 및 스타일링
  • Flutter와의 간편한 통합
  • 오픈소스이며 커뮤니티에서 지원합니다

적합한 대상

  • 캘린더 기반 앱을 개발하는 개발자
  • 인터랙티브한 시간 시각화가 필요한 앱
  • 경량 캘린더 위젯이 필요한 프로젝트
  • 투명하고 오픈소스 솔루션을 원하는 팀
  • 유연한 레이아웃 옵션을 찾는 디자이너

고려 사항

  • 특정 플랫폼 최적화에 대한 언급 없음
  • 기본 설정 외에 문서가 제한적
  • 이벤트 데이터를 수동으로 처리해야 합니다
  • 대규모 데이터 세트에 최적화되지 않음
  • 내장된 로컬라이제이션 지원 없음

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

📅 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 MonthWidgets 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: A DateTime with a time of zero.
  • month: A DateTime with a time of zero and a day of one.
  • timeOfDay: A Duration between zero and 24 hours.
  • dayOfWeek: An int between one and seven (DateTime.monday through DateTime.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 Events

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 your controller, e.g., in State.dispose!

Here are some of the available VisibleDateRanges:

  • VisibleDateRange.days: displays visibleDayCount consecutive days, snapping to every swipeRange days (aligned to alignmentDate) in the range from minDate to maxDate
  • VisibleDateRange.week: displays and snaps to whole weeks with a customizable startOfWeek in the range from minDate to maxDate
  • VisibleDateRange.weekAligned: displays visibleDayCount consecutive days while snapping to whole weeks with a customizable firstDay in the range from minDate to maxDate – 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 time's extension methods on int to create a Duration more concisely.

Don't forget to 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 a custom TimetableThemeData.

To apply your own theme, specify it in the TimetableConfig<E> (or directly in a TimetableTheme):

TimetableConfig<BasicEvent>(
  theme: TimetableThemeData(
    context,
    startOfWeek: DateTime.monday,
    dateDividersStyle: DateDividersStyle(
      context,
      color: Colors.blue.withOpacity(.3),
      width: 2,
    ),
    dateHeaderStyleProvider: (date) =>
        DateHeaderStyle(context, date, tooltip: 'My custom tooltip'),
    nowIndicatorStyle: NowIndicatorStyle(
      context,
      lineColor: Colors.green,
      shape: TriangleNowIndicatorShape(color: Colors.green),
    ),
    // See the "Theming" section below for more.
  ),
  // Other properties...
)

TimetableThemeData and all component styles provide two constructors each:

  • The default constructor takes a BuildContext and sometimes a day or month, using information from the ambient theme and locale to generate default values. You can still override all options via optional, named parameters.
  • The named raw constructor is usually const and has required parameters for all options.

Advanced Features

Drag and Drop
Drag and Drop demo

You can easily make events inside the content area of MultiDateTimetable or RecurringMultiDateTimetable draggable by wrapping them in a PartDayDraggableEvent:

PartDayDraggableEvent(
  // The user started dragging this event.
  onDragStart: () {},
  // The event was dragged to the given [DateTime].
  onDragUpdate: (dateTime) {},
  // The user finished dragging the event and landed on the given [DateTime].
  onDragEnd: (dateTime) {},
  child: MyEventWidget(),
  // By default, the child is displayed with a reduced opacity when it's
  // dragged. But, of course, you can customize this:
  childWhileDragging: OptionalChildWhileDragging(),
)

Timetable doesn't automatically show a moving feedback widget at the current pointer position. Instead, you can customize this and, e.g., snap event starts to multiples of 15 minutes. Have a look at the included example app where we implemented exactly that by displaying the drag feedback as a time overlay.

If you have widgets outside of timetable that can be dragged into timetable, you have to give your MultiDateContent and each PartDayDraggableEvent a geometryKey. A geometryKey is a GlobalKey<MultiDateContentGeometry> with which the current drag offset can be converted to a DateTime.

final geometryKey = GlobalKey<MultiDateContentGeometry>();

final timetable = MultiDateTimetable(contentGeometryKey: geometryKey);
// Or `MultiDateContent(geometryKey: geometryKey)` if you build your timetable
// from the provided, modular widgets.

final draggableEvent = PartDayDraggableEvent.forGeometryKeys(
  {geometryKey},
  // `child`, `childWhileDragging`, and the callbacks are available here as
  // well.
);

// Alternatively, you can manually convert an offset to a `DateTime:`
final dateTime = geometryKey.currentState!.resolveOffset(globalOffset);

You could even offer to drag the event into one of multiple timetables: Give each timetable its own geometryKey and pass all of them to PartDayDraggableEvent.forGeometryKeys. In the callbacks, you receive the geometryKey of the timetable that the event is currently being dragged over. See PartDayDraggableEvent.geometryKeys for the exact behavior.

Time Overlays
Drag and Drop demo

In addition to displaying events, MultiDateTimetable and RecurringMultiDateTimetable can display overlays for time ranges on every day. In the screenshot above, a light gray overlay is displayed on weekdays before 8 a.m. and after 8 p.m., and over the full day for weekends. Time overlays are provided similarly to events: Just add a timeOverlayProvider to your TimetableConfig<E> (or use a DefaultTimeOverlayProvider directly).

TimetableConfig<MyEvent>(
  timeOverlayProvider: (context, date) => <TimeOverlay>[
    TimeOverlay(
      start: 0.hours,
      end: 8.hours,
      widget: ColoredBox(color: Colors.black12),
      position: TimeOverlayPosition.behindEvents, // the default, alternatively `inFrontOfEvents`
    ),
    TimeOverlay(
      start: 20.hours,
      end: 24.hours,
      widget: ColoredBox(color: Colors.black12),
    ),
  ],
  // Other properties...
)

The provider is just a function that receives a date and returns a list of TimeOverlay for that date. The example above therefore draws a light gray background before 8 a.m. and after 8 p.m. on every day.

카테고리

의존성

의존성 목록 7 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.