The Flutter system provides several date-selection components, such as DayPicker, MonthPicker, YearPicker, showDatePicker, CupertinoDatePicker, etc. The first four of these components are Material style components. The last one is an ios-style component. This article covers the basic usage of controls and how to implement internationalization, and also how to implement custom internationalization if the internationalization provided by the system does not meet your needs.

DayPicker

Displays the date of the given month and allows you to select a day. These days are arranged in a rectangular grid, one column for each day of the week.

DayPicker has several mandatory parameters, as follows:

  • SelectedDate: the selectedDate with a circular background.
  • CurrentDate: indicates the currentDate, with text highlighted.
  • OnChanged: Callback when the date selected by the user changes.
  • FirstDate: start value of an optional date.
  • LastDate: End value of an optional date.
  • DisplayedMonth: indicates the month to display

The year May 2020 is displayed with the following code:

DateTime _selectedDate = DateTime.now();

DayPicker(
  selectedDate: _selectedDate,
  currentDate: DateTime.now(),
  onChanged: (date) {
    setState(() {
      _selectedDate = date;
    });
  },
  firstDate: DateTime(2020.5.1),
  lastDate: DateTime(2020.5.31),
  displayedMonth: DateTime(2020.5),Copy the code

The effect is as follows:

The selectableDayPredicate parameter defines optional dates for the user, returning false to indicate that these are not optional, such as dates prior to today only:

DayPicker(
  selectableDayPredicate: (date) {
    return date.difference(DateTime.now()).inMilliseconds < 0; },...).Copy the code

The effect is as follows:

All dates after today are grey and cannot be selected.

MonthPicker

MonthPicker MonthPicker MonthPicker MonthPicker MonthPicker MonthPicker MonthPicker MonthPicker MonthPicker

DateTime _selectedDate = DateTime.now();
MonthPicker(
  selectedDate: _selectedDate,
  onChanged: (date) {
    setState(() {
      _selectedDate = date;
    });
  },
  firstDate: DateTime(2020.1),
  lastDate: DateTime(2020.12),Copy the code

The effect is as follows:

Properties are basically the same as DayPicker.

YearPicker

The year selector is used as follows:

YearPicker(
  selectedDate: _selectedDate,
  onChanged: (date) {
    setState(() {
      _selectedDate = date;
    });
  },
  firstDate: DateTime(2000.1),
  lastDate: DateTime(2020.12),Copy the code

The effect is as follows:

The year selector is slightly different from the month selector in that the year selector does not contain the month under the current year.

Whether YearPicker, MonthPicker, or DayPicker, “we rarely use it directly,” instead using showDatePicker, which creates a date picker dialog. In my opinion, the style of showDatePicker is not very consistent with the aesthetic of China. We may use YearPicker, MonthPicker and DayPicker to customize the date control.

showDatePicker

ShowDatePicker is not a new control, but encapsulates YearPicker and MonthPicker, and uses them as follows:

RaisedButton(
  onPressed: () async {
    var result = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2020),
        lastDate: DateTime(2030));
    print('$result'); },)Copy the code

The effect is as follows:

Related parameters are described as follows:

  • InitialDate Initialization time, usually set to the current time.

  • FirstDate indicates the start time. The time before this time cannot be selected.

  • LastDate indicates the end time. You cannot select a time after this time.

  • The showDatePicker method is the Future method that returns the selected date after clicking ok on the date selection control.

  • The selectableDayPredicate parameter defines the optional date for the user, returning false to indicate that the date is not optional, the same as the DayPicker.

The Builder parameter can be used to wrap dialog widgets to add inherited widgets, such as Theme, to set a dark Theme as follows:

showDatePicker(
  builder: (context, child) {
    returnTheme( data: ThemeData.dark(), child: child, ); },...).Copy the code

The effect is as follows:

Here is the Material style date control. Here is the ios-style date control.

CupertinoDatePicker

Ios style date picker, used as follows:

 var _dateTime = DateTime.now(); CupertinoDatePicker( initialDateTime: _dateTime, onDateTimeChanged: (date) { setState(() { _dateTime = date; }); },)Copy the code

The effect is as follows:

The mode parameter sets the date format:

  • Time: displays only the time.4 | 14 | PM
  • Date: displays only the date.July | 13 | 2012
  • DateAndTime: displays both the time and the date.Fri Jul 13 | 4 | 14 | PM

Set maximum date and minimum date:

CupertinoDatePicker(
  minimumDate: DateTime.now().add(Duration(days: - 1)),
  maximumDate: DateTime.now().add(Duration(days: 1)),...).Copy the code

The effect is as follows:

Using 24-hour system:

CupertinoDatePicker(
  use24hFormat: true,...).Copy the code

showTimePicker

The time picker can only be called by showTimePicker as follows:

RaisedButton(
  onPressed: () async{ showTimePicker( context: context, initialTime: TimeOfDay.now()); },)Copy the code

The effect is as follows:

The Builder parameter is used to control the child control. It can be set to a dark theme like the DatePicker, and it can be set to display for 24 hours.

showTimePicker(
    context: context,
    initialTime: TimeOfDay.now(),
    builder: (context, child) {
      return MediaQuery(
        data: MediaQuery.of(context)
            .copyWith(alwaysUse24HourFormat: true),
        child: child,
      );
    });
Copy the code

The effect is as follows:

CupertinoTimerPicker

CupertinoTimerPicker is an ios style time picker. The basic usage is as follows:

CupertinoTimerPicker(
  onTimerDurationChanged: (Duration duration){
  },
)
Copy the code

The effect is as follows:

Set to display only hours and minutes:

CupertinoTimerPicker(
  mode: CupertinoTimerPickerMode.hm,
  ...
)
Copy the code

By default, CupertinoTimerPicker displays 0:0:0, set to display the current time:

var now = DateTime.now();
return Container(
  height: 200,
  child: CupertinoTimerPicker(
    initialTimerDuration: Duration(hours: now.hour,minutes: now.minute,seconds: now.second),
    onTimerDurationChanged: (Duration duration) {},
  ),
);
Copy the code

internationalization

Added internationalization handling and support in pubspec.yaml:

dependencies:
  flutter_localizations:
    sdk: flutter    
Copy the code

Add support to the top-level control Of The MaterialApp. Details can be found in the MaterialApp control:

MaterialApp(
  localeListResolutionCallback:
          (List<Locale> locales, 可迭代<Locale> supportedLocales) {
        return Locale('zh');
      },
      localeResolutionCallback:
          (Locale locale, 可迭代<Locale> supportedLocales) {
        return Locale('zh');
      },
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('zh'.'CH'),
        const Locale('en'.'US'),],...).Copy the code

The above method works for all date controls as follows:

Custom internationalization

For example, we create a new class MyLocalizationsDelegate for ios-style controls:

class MyLocalizationsDelegate
    extends LocalizationsDelegate<CupertinoLocalizations> {
  const MyLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => locale.languageCode == 'zh';

  @override
  Future<CupertinoLocalizations> load(Locale locale) =>
      ZhCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(MyLocalizationsDelegate old) => false;

  @override
  String toString() => 'DefaultCupertinoLocalizations.delegate(zh)';
}
Copy the code

Definitions are as follows:

class ZhCupertinoLocalizations implements CupertinoLocalizations {
  const ZhCupertinoLocalizations();

  static const List<String> _shortWeekdays = <String> ['Since Monday'.'Since Tuesday'.'Since Wednesday'.'Since Thursday'.'Since Friday'.'Since Saturday'.'Since Sunday',];static const List<String> _shortMonths = <String> ['1 month'.'2 months'.'march'.'in April'.'may'.'June'.'July'.'August'.'September'.'October'.'November'.'12 months',];static const List<String> _months = <String> ['1 month'.'2 months'.'march'.'in April'.'may'.'June'.'July'.'August'.'September'.'October'.'November'.'12 months',];@override
  String datePickerYear(int yearIndex) => yearIndex.toString();

  @override
  String datePickerMonth(int monthIndex) => _months[monthIndex - 1];

  @override
  String datePickerDayOfMonth(int dayIndex) => dayIndex.toString();

  @override
  String datePickerHour(int hour) => hour.toString();

  @override
  String datePickerHourSemanticsLabel(int hour) => hour.toString() + " o'clock";

  @override
  String datePickerMinute(int minute) => minute.toString().padLeft(2.'0');

  @override
  String datePickerMinuteSemanticsLabel(int minute) {
    if (minute == 1) return '1';
    return minute.toString() + 'points';
  }

  @override
  String datePickerMediumDate(DateTime date) {
    return '${_shortWeekdays[date.weekday - DateTime.monday]} '
        '${_shortMonths[date.month - DateTime.january]} '
        '${date.day.toString().padRight(2)}';
  }

  @override
  DatePickerDateOrder get datePickerDateOrder => DatePickerDateOrder.mdy;

  @override
  DatePickerDateTimeOrder get datePickerDateTimeOrder =>
      DatePickerDateTimeOrder.date_time_dayPeriod;

  @override
  String get anteMeridiemAbbreviation => 'morning';

  @override
  String get postMeridiemAbbreviation => 'afternoon';

  @override
  String get todayLabel => 'today';

  @override
  String get alertDialogLabel => 'Alert';

  @override
  String timerPickerHour(int hour) => hour.toString();

  @override
  String timerPickerMinute(int minute) => minute.toString();

  @override
  String timerPickerSecond(int second) => second.toString();

  @override
  String timerPickerHourLabel(int hour) => hour == 1 ? 'hour' : 'hour';

  @override
  String timerPickerMinuteLabel(int minute) => 'points.;

  @override
  String timerPickerSecondLabel(int second) => 's.;

  @override
  String get cutButtonLabel => 'clip';

  @override
  String get copyButtonLabel => 'copy';

  @override
  String get pasteButtonLabel => 'paste';

  @override
  String get selectAllButtonLabel => 'Select all';

  static Future<CupertinoLocalizations> load(Locale locale) {
    return SynchronousFuture<CupertinoLocalizations>(
        const ZhCupertinoLocalizations());
  }

  /// A [LocalizationsDelegate] that uses [DefaultCupertinoLocalizations.load]
  /// to create an instance of this class.
  static const LocalizationsDelegate<CupertinoLocalizations> delegate =
      MyLocalizationsDelegate();
}
Copy the code

Notice the start attribute _shortWeekdays, which represents the day of the week, purposely written ‘since week X’, in the localizationsDelegates property of the root control MaterialApp: ZhCupertinoLocalizations. Delegate, and this is the internationalization of the above definition file, results are as follows:

Note: ZhCupertinoLocalizations. Delegate to put GlobalCupertinoLocalizations. Delegate, in front of, the system load order from top to bottom.

The effect is as follows:

communication

Old Meng Flutter blog address (nearly 200 controls usage) : laomengit.com