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

date_picker_plus 표지
패키지 상세v8.0.0

date_picker_plus

사용자 정의 가능한 Material Design 날짜 및 범위 선택 위젯을 제공하는 플러터 라이브러리입니다.

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
2.5만
좋아요
102
Pub 점수
160

패키지 설치

flutter pub add date_picker_plus

패키지 개요

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

사용자 정의 가능한 마테리얼 디자인 날짜 및 범위 선택 위젯을 제공하는 플러터 라이브러리입니다. 안드로이드, iOS, 웹, macOS, Windows, 리눅스 등 모든 주요 플랫폼을 지원합니다. 이 패키지는 마테리얼 디자인 원칙에 부합하는 직관적이고 시각적으로 일관된 날짜 선택 인터페이스를 통해 사용자 경험을 향상시킵니다. 개발자는 앱 테마와 요구 사항에 맞게 선택기의 외관과 동작을 쉽게 조정할 수 있습니다. 유연성과 통합 용이성을 위해 설계되어 플러터 애플리케이션에서 날짜 입력을 처리하는 것을 간소화합니다.

사용 사례

  • 폼 날짜 입력
  • 예약 또는 스케줄링 앱
  • 이벤트 기획 도구
  • 사용자 프로필 설정
  • 날짜별 데이터 필터링
  • 다일 이벤트 선택

주요 기능

  • 사용자 지정 가능한 UI
  • Material Design 준수
  • 범위 날짜 선택기 지원
  • 크로스 플랫폼 호환성
  • 폼과의 간편한 통합
  • 테마 인식 스타일링

적합한 대상

  • 양식 중심 앱을 개발하는 개발자
  • 날짜 선택이 필요한 앱
  • Material Design를 사용하는 팀
  • 크로스 플랫폼 Flutter 프로젝트
  • 사용자 인터페이스 중심의 날짜 입력 솔루션

고려 사항

  • 비 Material 디자인의 경우 수동 테마 구성이 필요합니다
  • Material 사양을 초과한 사용자 지정은 제한적입니다
  • 내장된 검증 없음
  • 추가적인 로컬라이제이션 설정이 필요할 수 있습니다
  • 복잡한 캘린더 로직에 최적화되지 않음
  • Flutter의 Material 패키지에 의존합니다

원본 README

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

Tests

Date Picker Plus

A Flutter package with highly customizable Material date and range pickers.

1 2 3 4

Features

  • Material 3 friendly out of the box.
  • Rich theming via one top-level theme object.
  • Inline widgets and dialog helpers.
  • Powerful cellBuilder for custom content inside cells.
  • Built-in localization support.
  • View-only mode for read-only calendars.

Install

dependencies:
  date_picker_plus: ^8.0.0
import 'package:date_picker_plus/date_picker_plus.dart';

Quick Start

Show a date picker dialog
final date = await showDatePickerDialog(
  context: context,
  minDate: DateTime(2020, 1, 1),
  maxDate: DateTime(2030, 12, 31),
);
Show a range picker dialog
final range = await showRangePickerDialog(
  context: context,
  minDate: DateTime(2020, 1, 1),
  maxDate: DateTime(2030, 12, 31),
);
Use an inline picker widget
SizedBox(
  width: 320,
  height: 400,
  child: DatePicker(
    minDate: DateTime(2020, 1, 1),
    maxDate: DateTime(2030, 12, 31),
    onDateSelected: (date) {},
  ),
);

Available Widgets

DatePicker

Use this for a full single-date picker with days, months, and years flow.

RangeDatePicker

Use this when users must select a start and end date. It supports:

  • onRangeSelected for the final result.
  • onStartDateChanged and onEndDateChanged for step-by-step tracking.
DaysPicker

Use this if you want day-only selection UI.

MonthPicker

Use this for month-only selection.

YearsPicker

Use this for year-only selection.

showDatePickerDialog and showRangePickerDialog

Use these when you want ready-made dialogs returning:

  • Future<DateTime?>
  • Future<DateTimeRange?>

Sizing and Layout

Always give inline pickers a size

In unconstrained layouts (for example inside some Column, Row, or scrollable situations), pickers fall back to internal limits through a LimitedBox (portrait around 328x402, landscape around 328x300). If you need exact behavior, wrap the picker with SizedBox.

SizedBox(
  width: 280,
  height: 360,
  child: DatePicker(
    minDate: DateTime(2020),
    maxDate: DateTime(2050),
  ),
);

The widgets also work at very small sizes (for example 100x100) if your content choices (font size, padding, custom cell UI) fit.

Dialog size and paddings

showDatePickerDialog and showRangePickerDialog default to:

  • Portrait: 328x400
  • Landscape: 328x300

You can override with width and height.

There are two different paddings:

  • padding: outside the dialog widget itself (default EdgeInsets.all(36)).
  • contentPadding: inside the picker content area (default EdgeInsets.all(16)).
Dialog background

Use dialogBackground to set the background color of the dialog surface behind the picker:

final date = await showDatePickerDialog(
  context: context,
  minDate: DateTime(2020, 1, 1),
  maxDate: DateTime(2030, 12, 31),
  dialogBackground: Colors.white,
);

It is available on both showDatePickerDialog and showRangePickerDialog. When omitted, the ambient DialogTheme / Material default background applies.

Theming Model

DatePickerPlusTheme is a ThemeExtension.

DatePickerPlusTheme
  +-- headerTheme
  +-- daysPickerTheme
  |     +-- daysOfTheWeekTheme
  +-- monthsPickerTheme
  +-- yearsPickerTheme
  +-- rangePickerTheme
  +-- isEnabled
  +-- locale

Picker theme resolution is merged in this order:

  1. Internal defaults: DatePickerPlusTheme.defaults(context) (Material ColorScheme / TextTheme, intl first day of week, optional Material page labels)
  2. App-level extension from ThemeData.extensions
  3. Per-widget theme: argument
Set app-wide overrides once
MaterialApp(
  theme: ThemeData(
    extensions: const [
      DatePickerPlusTheme(
        headerTheme: HeaderTheme(centerLeadingDate: true),
      ),
    ],
  ),
  home: const MyHomePage(),
);
InkResponseTheme

If you want to control interaction feel (splash/highlight/focus/hover/radius/border behavior), set inkResponseTheme in the specific picker theme (daysPickerTheme, monthsPickerTheme, yearsPickerTheme, rangePickerTheme). This is useful when your cell shapes are custom and default ripple clipping does not match.

Header Customization

Hide header completely
theme: const DatePickerPlusTheme(
  headerTheme: HeaderTheme(enableHeader: false),
)
Hide arrow buttons
theme: const DatePickerPlusTheme(
  headerTheme: HeaderTheme(enableArrowKeys: false),
)
Center leading date text
theme: const DatePickerPlusTheme(
  headerTheme: HeaderTheme(centerLeadingDate: true),
)
Replace arrow icons
theme: const DatePickerPlusTheme(
  headerTheme: HeaderTheme(
    forwardArrowWidget: Icon(Icons.keyboard_arrow_right_rounded),
    backwardArrowWidget: Icon(Icons.keyboard_arrow_left_rounded),
  ),
)
Arrow button decoration must be ShapeDecoration

HeaderTheme.forwardButtonDecoration and HeaderTheme.backwardButtonDecoration accept ShapeDecoration (not BoxDecoration). This avoids ink clipping mismatches and guarantees shape-aware splash behavior.

theme: DatePickerPlusTheme(
  headerTheme: HeaderTheme(
    forwardButtonDecoration: ShapeDecoration(
      color: Colors.red,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
    ),
    backwardButtonDecoration: ShapeDecoration(
      color: Colors.red,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
    ),
  ),
)
Control spacing and sizing
  • headerPadding controls distance around header content.
  • arrowButtonsSpace controls spacing between arrow buttons.
  • forwardButtonWidth / forwardButtonHeight and backward equivalents control button size.

Weekday Row Behavior

Change first day of week

By default, the first day comes from locale (for example many en_GB setups start with Monday while many en_US setups start with Sunday). Override it using startOfWeek (ISO 8601 weekday number: 1 Monday ... 7 Sunday):

theme: const DatePickerPlusTheme(
  daysPickerTheme: DaysPickerTheme(
    daysOfTheWeekTheme: DaysOfTheWeekTheme(startOfWeek: DateTime.sunday),
  ),
)
Choose weekday label length

weekdayLength supports:

  • WeekdayLength.long (Monday)
  • WeekdayLength.short (Mon)
  • WeekdayLength.narrow (M)
theme: const DatePickerPlusTheme(
  daysPickerTheme: DaysPickerTheme(
    daysOfTheWeekTheme: DaysOfTheWeekTheme(
      weekdayLength: WeekdayLength.narrow,
    ),
  ),
)

Cell Layout and Padding

Cell padding vs grid padding
  • cellsPadding is per-cell inner spacing around the decorated cell content.
  • padding on each picker theme is spacing around the entire grid view.

Defaults worth knowing:

  • DaysPickerTheme.cellsPadding defaults to EdgeInsets.zero.
  • MonthsPickerTheme.cellsPadding and YearsPickerTheme.cellsPadding default to EdgeInsets.symmetric(horizontal: 8, vertical: 12).
Non-square cells are supported

Grid cell width and height are not forced to match. If your custom UI needs taller cells (events under the date number, badges, extra lines), this is supported naturally. If you increase vertical cell content heavily, review the range section below for edge-shape behavior.

Custom Cell Builder

cellBuilder gives you precise control over cell UI while preserving picker logic.

What cellBuilder receives

You get a CellData subtype:

  • WeekDayCell with weekDay (1..7, ISO 8601 weekday number)
  • DayCell with day (DateTime)
  • MonthCell with month and year
  • YearCell with year

data.child is the default decorated content for that cell. You can return it unchanged, wrap it, or fully replace it.

data.state can be:

  • disabled
  • enabled
  • selected
  • selectedEdge
  • current
  • currentAndDisabled

Precedence detail:

  • If a cell is both current and selected, it is reported as selected.
  • currentAndDisabled is used when current date exists but is not selectable.
Add a badge on a specific day
cellBuilder: (context, data) {
  if (data case DayCell cell when cell.day.day == 14) {
    return Stack(
      clipBehavior: Clip.none,
      children: [
        cell.child,
        const Positioned(
          right: 4,
          top: -2,
          child: Badge.count(count: 6),
        ),
      ],
    );
  }
  return data.child;
}
Replace a cell with an event layout
cellBuilder: (context, data) {
  if (data case DayCell cell when cell.day.day == 11) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        const SizedBox(height: 6),
        const Text('11'),
        const Spacer(),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            SizedBox(width: 2, height: 10),
            SizedBox(width: 4),
            Flexible(child: Text('Event', maxLines: 1, overflow: TextOverflow.ellipsis)),
          ],
        ),
      ],
    );
  }
  return data.child;
}

Range Picker Specific Behavior

Edge cells and in-range cells are different

Range theming distinguishes:

  • Start/end (or single selected edge): selectedEdgeCellDecoration, selectedEdgeCellTextStyle
  • Middle range cells: selectedCellsDecoration, selectedCellsTextStyle
Decoration color extraction limitation

When drawing range background behind edge cells, the package tries to extract color from the resolved in-range decoration. It currently extracts only from ShapeDecoration and BoxDecoration:

if (resolvedDecoration case ShapeDecoration(color: final color) || BoxDecoration(color: final color)) {
  decorationColor = color;
}

If you use any other Decoration implementation, color cannot be extracted automatically. In that case, provide your own resolvePainter.

Reuse the default painter with your own color
theme: DatePickerPlusTheme(
  rangePickerTheme: RangePickerTheme(
    selectedCellsDecoration: const MyFancyDecoration(),
    resolvePainter: (textDirection, _, start) {
      return RangeSelectionPainter(
        textDirection: textDirection,
        color: const Color(0xFFCCE5FF), // provide your intended range color
        start: start,
      );
    },
  ),
)
Non-square edge shape gap

If cells become taller than wide, a circular edge decoration can look visually detached from the full-height range background.

Fix options:

  • Use OvalBorder or StadiumBorder for edge shape.
  • Adjust cellsPadding to reduce height/width mismatch.
selectedEdgeCellDecoration: ShapeDecoration(
  color: colorScheme.primary,
  shape: const OvalBorder(),
)

Behavioral Features

Disable specific days

Use disabledDayPredicate in DatePicker / DaysPicker:

disabledDayPredicate: (date) {
  return date.weekday == DateTime.saturday || date.weekday == DateTime.sunday;
}
View-only mode

Set DatePickerPlusTheme.isEnabled to false:

  • No taps
  • No header navigation
  • No month swiping
  • Accessibility reports controls as disabled
theme: const DatePickerPlusTheme(isEnabled: false)
Start from month or year view
initialPickerType: PickerType.months
// or
initialPickerType: PickerType.years
Track displayed month changes

onDisplayedMonthChanged fires:

  • On initial build
  • On page swipes that change month

It passes the first day of the visible month.

Localization

Enable Flutter localization delegates and locales in your app:

MaterialApp(
  localizationsDelegates: GlobalMaterialLocalizations.delegates,
  locale: const Locale('en', 'US'),
  supportedLocales: const [
    Locale('en', 'US'),
    Locale('en', 'GB'),
    Locale('ar'),
    Locale('zh'),
    Locale('ru'),
    Locale('es'),
    Locale('hi'),
  ],
  home: const MyHomePage(),
);

Then optionally override first day of week via DaysOfTheWeekTheme.startOfWeek if locale default is not desired.

Migration from v6 to v7

Theming moved to one theme object

Per-widget visual parameters were removed. Use DatePickerPlusTheme and sub-themes.

// v6 style
DatePicker(
  minDate: minDate,
  maxDate: maxDate,
  slidersColor: Colors.blue,
  centerLeadingDate: true,
  selectedCellDecoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle),
);

// v7 style
DatePicker(
  minDate: minDate,
  maxDate: maxDate,
  theme: const DatePickerPlusTheme(
    headerTheme: HeaderTheme(centerLeadingDate: true),
    daysPickerTheme: DaysPickerTheme(
      selectedCellDecoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle),
    ),
  ),
);
initialDate renamed to displayedDate
// v6
showDatePickerDialog(
  context: context,
  minDate: minDate,
  maxDate: maxDate,
  initialDate: someDate,
);

// v7
showDatePickerDialog(
  context: context,
  minDate: minDate,
  maxDate: maxDate,
  displayedDate: someDate,
);
Header button decoration type changed

forwardButtonDecoration and backwardButtonDecoration now use ShapeDecoration.

Semantic label overrides removed

previousPageSemanticLabel and nextPageSemanticLabel are no longer exposed. Material localizations are used internally.

Contribution

Contributions are welcome. If you find a bug or want a feature, open an issue or PR on the GitHub repository.

Before creating a PR:

  • Cover new features with tests.
  • Ensure tests pass.
  • Open an issue/feature discussion before large work.
  • Provide a minimal reproducible example for reported issues.
  • Use the official Dart Extension formatter (or flutter format .).
  • Keep changes focused and minimal.

License

This project is licensed under the MIT License. See LICENSE.

카테고리

의존성

의존성 목록 2 개

소스 저장소

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

아직 데이터가 없습니다.