material_drum_picker 1.2.0 copy "material_drum_picker: ^1.2.0" to clipboard
material_drum_picker: ^1.2.0 copied to clipboard

A Material 3 date picker with an iOS-style drum roller, full API parity with showDatePicker and CupertinoDatePicker, and drum, calendar and input modes.

material_drum_picker #

pub package pub points likes CI License: MIT

A Material Design 3 date, time, and date+time picker with an iOS style drum roller. It offers full API parity with Flutter's showDatePicker and CupertinoDatePicker, uses Material 3 color tokens, and ships three context aware date modes (drum, calendar, and keyboard input).

Showcase #

Every look below is rendered straight from the package: the drum mode (with day of week), the calendar mode (quick selects plus disabled weekends), the keyboard input mode, a combined date and time picker, and a dark theme.

[material_drum_picker showcase]

Run the live demo for every option with cd example && flutter run, then open the Showcase screen.

Features #

  • Drum mode. An iOS style scroll wheel. Ideal for birth dates and expiry dates.
  • Calendar mode. A Material 3 calendar grid with year navigation and configurable quick select chips.
  • Input mode. A keyboard text field with live MM/DD/YYYY validation.
  • Date and time. Opt in with pickTime: true (or showDrumDateTimePicker) to add an hour and minute drum, plus an AM/PM column in 12 hour mode.
  • Time only. Use DrumTimePicker or showDrumTimePicker to pick just a TimeOfDay, configurable for AM/PM or 24 hour mode.
  • Full API parity with showDatePicker and CupertinoDatePicker. Shared parameters keep the same names so migration is a one line change.
  • selectableDayPredicate to disable weekends, holidays, or any custom rule, enforced in all three date modes.
  • quickSelectOptions for custom chips such as Today, Next Monday, or +3 Days.
  • columnOrder for Day/Month/Year, Month/Day/Year, or Year/Month/Day.
  • Material 3 theming through ColorScheme tokens, with per app overrides via the DrumPickerTheme extension.
  • Right to left support for Arabic, Hebrew, and Persian, with the weekday and column order flipping automatically.
  • Accessibility: 44dp touch targets, keyboard navigation in the calendar, screen reader semantics, and reduced motion support.
  • All six platforms: Android, iOS, web, macOS, Windows, and Linux.
  • Zero runtime dependencies beyond Flutter and intl.

Pickers at a glance #

Function Returns Use it for
showDrumDatePicker DateTime? A date
showDrumDateTimePicker DateTime? A date and a time
showDrumTimePicker TimeOfDay? A time only

Each function has an inline widget equivalent (DrumPicker and DrumTimePicker) for embedding in a form without a dialog.

Date and time #

[date and time picker]

Time only #

[time picker]

Installation #

dependencies:
  material_drum_picker: ^1.2.0

Add flutter_localizations to your app if you have not already:

dependencies:
  flutter_localizations:
    sdk: flutter

Then register the delegates in your MaterialApp:

MaterialApp(
  localizationsDelegates: GlobalMaterialLocalizations.delegates,
  supportedLocales: const [Locale('en'), /* your locales */],
)

Quick start #

A date (drop in replacement for showDatePicker) #

import 'package:material_drum_picker/material_drum_picker.dart';

final DateTime? picked = await showDrumDatePicker(
  context: context,
  firstDate: DateTime(1900),
  lastDate: DateTime(2100),
);

A time only #

final TimeOfDay? time = await showDrumTimePicker(
  context: context,
  initialTime: TimeOfDay.now(),
  use24hFormat: true,   // null follows MediaQuery.alwaysUse24HourFormat
  minuteInterval: 5,    // 0, 5, 10, ...
);

Inline, embedded in a form:

DrumTimePicker(
  initialTime: const TimeOfDay(hour: 9, minute: 0),
  use24hFormat: false,  // shows an AM/PM column
  minuteInterval: 15,
  showActions: false,
  onChanged: (time) => setState(() => _time = time),
)

A date and time #

final DateTime? when = await showDrumDateTimePicker(
  context: context,
  firstDate: DateTime(2020),
  lastDate: DateTime(2030),
  use24hFormat: true,
  minuteInterval: 15,
);
// `when` carries the chosen hour and minute.

Birth date picker #

final today = DateTime.now();
final birthDate = await showDrumDatePicker(
  context: context,
  initialMode: DrumPickerMode.drum,        // a wheel for distant dates
  firstDate: DateTime(today.year - 120),
  lastDate: DateTime(today.year - 18, today.month, today.day),
  columnOrder: DrumColumnOrder.dmy,        // Day, Month, Year
  showModeToggle: false,                   // lock to drum mode
  helpText: 'SELECT BIRTH DATE',
);

Appointment picker without weekends #

final appointment = await showDrumDatePicker(
  context: context,
  initialMode: DrumPickerMode.calendar,
  firstDate: DateTime.now(),
  lastDate: DateTime.now().add(const Duration(days: 90)),
  selectableDayPredicate: (day) =>
      day.weekday != DateTime.saturday && day.weekday != DateTime.sunday,
  confirmText: 'BOOK APPOINTMENT',
);

Custom quick selects #

showDrumDatePicker(
  context: context,
  firstDate: DateTime.now().add(const Duration(days: 1)),
  lastDate: DateTime.now().add(const Duration(days: 30)),
  quickSelectOptions: [
    DrumQuickSelect.relative(label: 'Express +1',  offset: const Duration(days: 1)),
    DrumQuickSelect.relative(label: 'Standard +3', offset: const Duration(days: 3)),
    DrumQuickSelect.relative(label: 'Economy +7',  offset: const Duration(days: 7)),
  ],
);

API reference #

showDrumDatePicker and showDrumDateTimePicker #

Parameter Type Default Description
context BuildContext required Build context
firstDate DateTime required Minimum selectable date
lastDate DateTime required Maximum selectable date
initialDate DateTime? today Pre selected date
currentDate DateTime? DateTime.now() The "today" marker
selectableDayPredicate SelectableDayPredicate? null Return false to disable a day
initialMode DrumPickerMode .drum Starting date mode
showModeToggle bool true Show the mode tabs
columnOrder DrumColumnOrder? locale default Column order in drum mode
showDayOfWeekInDrum bool false Show weekday in the drum day column
showQuickSelects bool true Show quick select chips
quickSelectOptions List<DrumQuickSelect>? Today/Tomorrow/+7d Custom chips
pickTime bool false Also pick a time of day
use24hFormat bool? ambient 24 hour time strip (no AM/PM)
minuteInterval int 1 Minute granularity (a divisor of 60)
helpText String? 'SELECT DATE' Header label
confirmText String? 'OK' Confirm button text
cancelText String? 'Cancel' Cancel button text
errorFormatText String? 'Invalid format' Input mode format error
errorInvalidText String? 'Out of range' Input mode range error
fieldHintText String? 'MM/DD/YYYY' Input field hint
fieldLabelText String? 'Enter Date' Input field label
locale Locale? ambient Locale override
textDirection TextDirection? ambient Text direction override
barrierDismissible bool true Tap outside to dismiss
barrierColor Color? Colors.black54 Barrier color
barrierLabel String? localized Barrier accessibility label
useRootNavigator bool true Use the root navigator
routeSettings RouteSettings? null Route settings
restorationId String? null State restoration id
anchorPoint Offset? null Split screen anchor
builder TransitionBuilder? null Wrap the dialog with a Theme, and so on

showDrumDateTimePicker takes the same parameters and is simply showDrumDatePicker with pickTime set to true.

showDrumTimePicker #

Parameter Type Default Description
context BuildContext required Build context
initialTime TimeOfDay? now Pre selected time
use24hFormat bool? ambient 24 hour mode (no AM/PM column)
minuteInterval int 1 Minute granularity (a divisor of 60)
helpText String? 'SELECT TIME' Header label
confirmText String? 'OK' Confirm button text
cancelText String? 'Cancel' Cancel button text
locale Locale? ambient Locale override
textDirection TextDirection? ambient Text direction override
barrierDismissible bool true Tap outside to dismiss
barrierColor Color? Colors.black54 Barrier color
barrierLabel String? null Barrier accessibility label
useRootNavigator bool true Use the root navigator
routeSettings RouteSettings? null Route settings
anchorPoint Offset? null Split screen anchor
builder TransitionBuilder? null Wrap the dialog with a Theme, and so on

Inline widgets #

DrumPicker accepts every showDrumDatePicker parameter, plus the callbacks onChanged, onConfirmed, onCancelled, and onModeChanged, and the showActions flag. DrumTimePicker accepts every showDrumTimePicker parameter, plus onChanged, onConfirmed, onCancelled, and showActions. Set showActions: false to drop the built in Cancel and OK buttons and drive the value yourself with onChanged.

DrumColumnOrder #

Value Format Typical regions
dmy 15 Jun 2024 UK, Europe, MENA, Australia
mdy Jun 15 2024 United States, Canada
ymd 2024 Jun 15 Japan, China, Korea
ydm 2024 15 Jun Rarely used

DrumPickerMode #

Value Best for
drum Birth dates, expiry dates, distant past or future
calendar Scheduling events, appointments, near future
input Power users, accessibility tools, typed entry

DrumPickerTheme #

Add it to ThemeData.extensions to override individual tokens:

ThemeData(
  useMaterial3: true,
  extensions: const [
    DrumPickerTheme(
      headerBackgroundColor: Color(0xFF004D40),
      headerTextColor: Colors.white,
      itemExtent: 48,
      visibleItemCount: 3,
    ),
  ],
)

Localization #

The pickers follow the ambient locale for month and weekday names, the first day of the week, AM/PM labels, the column order, and right to left layout. Pass locale and textDirection to override them for a single picker. The time format follows MediaQuery.alwaysUse24HourFormat unless you set use24hFormat.

Migration from showDatePicker #

Most parameters keep the same name, so usually only the function name changes:

// Before
showDatePicker(
  context: context,
  initialDate: myDate,
  firstDate: DateTime(1900),
  lastDate: DateTime(2100),
  selectableDayPredicate: myPredicate,
  helpText: 'PICK DATE',
  locale: myLocale,
);

// After, identical parameter names
showDrumDatePicker(
  context: context,
  initialDate: myDate,
  firstDate: DateTime(1900),
  lastDate: DateTime(2100),
  selectableDayPredicate: myPredicate,
  helpText: 'PICK DATE',
  locale: myLocale,
  initialMode: DrumPickerMode.calendar, // optional, same feel as showDatePicker
);

Contributing #

Contributions are welcome. Please read CONTRIBUTING.md for the development setup and the checks that run in CI, and note the Code of Conduct. To report a security issue, see SECURITY.md.

Roadmap #

  • v1.0 Single date picker (drum, calendar, and input modes).
  • v1.1 Combined date and time picking (pickTime, showDrumDateTimePicker).
  • v1.2 Standalone time picker (DrumTimePicker, showDrumTimePicker).
  • Next Date range selection (showDrumDateRangePicker).

License #

MIT, 2026. See LICENSE.

1
likes
0
points
179
downloads

Publisher

unverified uploader

Weekly Downloads

A Material 3 date picker with an iOS-style drum roller, full API parity with showDatePicker and CupertinoDatePicker, and drum, calendar and input modes.

Repository (GitHub)
View/report issues

Topics

#date-picker #material #material-3 #ui #widget

License

unknown (license)

Dependencies

flutter, intl

More

Packages that depend on material_drum_picker