https://api.flutter.dev/flutter/material/showDatePicker.html

在 Flutter 里没有对应的组件,而是提供两个函数:showDatePicker() 和 showTimePicker()。

showDatePicker 官方日期组件

image.png

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. class DatePickerDemo extends StatefulWidget {
  4. @override
  5. _DatePickerDemoState createState() => _DatePickerDemoState();
  6. }
  7. class _DatePickerDemoState extends State<DatePickerDemo> {
  8. static DateTime now = DateTime.now();
  9. DateTime _date = now;
  10. _openDate() {
  11. showDatePicker(
  12. context: context,
  13. initialDate: _date, //初始化日期(选中日期),组件上会高亮背景标识
  14. currentDate: now, //当前日期(一般设为今天,组件上会用 幽灵按钮样式圈中)
  15. firstDate: now.subtract(Duration(days: 30)), //起始日期,超出范围后不能选择
  16. lastDate: now.add(Duration(days: 30)), //终止日期
  17. initialEntryMode: DatePickerEntryMode.calendar, //calendar 默认; input 只可以输入,不能选择
  18. helpText: '帮助', //顶部帮助信息
  19. cancelText: '取消', //置换cancel按钮文本
  20. confirmText: '确定', //置换ok按钮文本
  21. // useRootNavigator: false, //是否显示导航指示信息,默认为true
  22. ).then((v) {
  23. setState(() {
  24. _date = (v ?? _date);
  25. });
  26. });
  27. }
  28. @override
  29. Widget build(BuildContext context) {
  30. return Container(
  31. child: Column(
  32. children: [
  33. InkWell(
  34. child: Row(
  35. children: [
  36. Text(formatDate(_date, [yyyy, '-', mm, '-', dd]), textScaleFactor: 3),
  37. Icon(Icons.arrow_drop_down),
  38. ],
  39. ),
  40. onTap: this._openDate,
  41. ),
  42. ],
  43. ),
  44. );
  45. }
  46. }

showTimePicker 官方时间组件

image.png

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. class DatePickerDemo extends StatefulWidget {
  4. @override
  5. _DatePickerDemoState createState() => _DatePickerDemoState();
  6. }
  7. class _DatePickerDemoState extends State<DatePickerDemo> {
  8. static var now = DateTime.now();
  9. static var nowTime = TimeOfDay.fromDateTime(now);
  10. TimeOfDay _time = nowTime;
  11. _openTime() {
  12. showTimePicker(
  13. context: context,
  14. initialTime: _time,
  15. initialEntryMode: TimePickerEntryMode.dial, //dial input
  16. ).then((v) {
  17. setState(() {
  18. _time = (v ?? _time);
  19. });
  20. });
  21. }
  22. @override
  23. Widget build(BuildContext context) {
  24. return InkWell(
  25. child: Row(
  26. children: [
  27. Text(_time.format(context), textScaleFactor: 3),
  28. Icon(Icons.arrow_drop_down),
  29. ],
  30. ),
  31. onTap: this._openTime,
  32. );
  33. }
  34. }

汉化

https://flutterchina.club/tutorials/internationalization/
https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html

(1)配置 flutter_localizations 依赖

  1. dependencies:
  2. flutter:
  3. sdk: flutter
  4. flutter_localizations:
  5. sdk: flutter

(2)导入flutter_localizations库,并指定MaterialApp的localizationsDelegatesupportedLocales

  1. import "package:flutter/material.dart";
  2. import 'package:flutter_localizations/flutter_localizations.dart';
  3. void main() => runApp(MyApp());
  4. class MyApp extends StatelessWidget {
  5. @override
  6. Widget build(BuildContext context) {
  7. return MaterialApp(
  8. //...
  9. localizationsDelegates: [
  10. // ... app-specific localization delegate[s] here
  11. GlobalMaterialLocalizations.delegate,
  12. GlobalWidgetsLocalizations.delegate,
  13. ],
  14. supportedLocales: [
  15. const Locale('en', 'US'), // English
  16. const Locale('zh', 'CH'), // China
  17. // ... other locales the app supports
  18. ],
  19. );
  20. }
  21. }

(3)要显示中文的控件设置:
如果手机系统是中文的话,showDatePicker就不需要再导入 locale: Locale('zh') 了。

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart' as DateFormat;
  3. //date_format库和flutter_localizations的库 Localel类 冲突
  4. class DatePickerDemo extends StatefulWidget {
  5. @override
  6. _DatePickerDemoState createState() => _DatePickerDemoState();
  7. }
  8. class _DatePickerDemoState extends State<DatePickerDemo> {
  9. static var now = DateTime.now();
  10. DateTime _date = now;
  11. _openDate() {
  12. showDatePicker(
  13. context: context,
  14. initialDate: _date,
  15. currentDate: now,
  16. firstDate: now.subtract(Duration(days: 30)),
  17. lastDate: now.add(Duration(days: 30)),
  18. locale: Locale('zh'),
  19. ).then((v) {
  20. setState(() {
  21. _date = (v ?? _date);
  22. });
  23. });
  24. }
  25. @override
  26. Widget build(BuildContext context) {
  27. return InkWell(
  28. child: Row(
  29. children: [
  30. Text(
  31. DateFormat.formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']),
  32. textScaleFactor: 3
  33. ),
  34. Icon(Icons.arrow_drop_down),
  35. ],
  36. ),
  37. onTap: this._openDate,
  38. );
  39. }
  40. }

库 flutter_cupertino_date_picker

https://pub.dev/packages/flutter_cupertino_date_picker
中文说明:https://github.com/dylanwuzh/flutter-cupertino-date-picker/blob/master/README_zh-cn.md
官方示例:https://github.com/dylanwuzh/flutter-cupertino-date-picker/tree/master/example/lib

Flutter 的日期选择器控件,iOS 样式。

1. 添加依赖

在项目的 pubspec.yaml 文件中添加依赖:

  1. dependencies:
  2. flutter_cupertino_date_picker: ^1.0.26+2

报错: Error: Type ‘DiagnosticableMixin’ not found. class DateTimePickerTheme with DiagnosticableMixin { 原因: flutter1.20.0+以上 the DiagnostableMixin is removed, instead Diagnostable

https://github.com/dylanwuzh/flutter-cupertino-date-picker/issues/132

It’s obsolete, someone made a fork that works, add this to your pubspec.yaml instead

  1. dependencies:
  2. flutter:
  3. sdk: flutter
  4. flutter_cupertino_date_picker:
  5. git:
  6. url: https://github.com/imshashank/flutter-cupertino-date-picker # Repo
  7. ref: master # Branch name

2. 获取包

执行 Flutter 的命令获取包资源:

  1. $ flutter packages get

3. 导入控件

在项目中导入该控件:

  1. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';

4. 显示控件

dateFormat 格式化

Pattern Meaning e.g.
yyyy 年份 2019, 2020
yy 年份, 2位数字 19, 20
MMMM 月份 January(en_us), 01(zh_cn)
MMM 月份, 缩写 Jan(en_us), 01(zh_cn)
MM 月份, 2位数字 01、11
M 月份 1, 11
dd 日期, 2位数字 05, 25
d 日期 5, 25
EEEE 星期 Monday(en_us), 星期一(zh_cn)
EEE 星期, 缩写 Mon(en_us), 周一(zh_cn)
HH 时 (0~23), 2位数字 04, 12, 20
H 时 (0~23) 4, 12, 20
mm 分, 2位数字 05, 40
m 5, 40
ss 秒, 2位数字 06, 55
s 6, 55
yyyy年 格式化 2019年, 2020年
H时 格式化 5时, 21时

Date Format Separator

支持的分隔符: |,-/\._:.

pickerTheme: DateTimePickerTheme, 日期时间选择器的样式

  1. const DateTimePickerTheme({
  2. this.backgroundColor: DATETIME_PICKER_BACKGROUND_COLOR, //背景色
  3. this.cancelTextStyle, //默认标题栏取消按钮的样式 [TextStyle]
  4. this.confirmTextStyle, //默认标题栏确定按钮的样式 [TextStyle]
  5. this.cancel, //自定义标题栏取消按钮
  6. this.confirm, //自定义标题栏确定按钮
  7. this.title, //自定义标题栏。如果指定了自定义标题栏,不显示默认的标题栏。
  8. //指定自定义的标题栏时必须指定 [titleHeight] 的值
  9. this.showTitle: DATETIME_PICKER_SHOW_TITLE_DEFAULT,
  10. //是否显示默认的标题栏。如果设置为false,默认的取消、确定按钮都不会显示,自定义的标题栏不受影响
  11. this.pickerHeight: DATETIME_PICKER_HEIGHT, //日期选择器的高度
  12. this.titleHeight: DATETIME_PICKER_TITLE_HEIGHT, //标题栏的高度
  13. this.itemHeight: DATETIME_PICKER_ITEM_HEIGHT, //选择器每一行的高度
  14. this.itemTextStyle: DATETIME_PICKER_ITEM_TEXT_STYLE, //选择器每一行的样式 [TextStyle]
  15. });

DatePicker方法,BottomSheet形式(底部滑出)

  1. DatePicker.showDatePicker(
  2. BuildContext context,
  3. DateTime minDateTime, //最小值
  4. DateTime maxDateTime, //最大值
  5. DateTime initialDateTime, //初始值
  6. String dateFormat, //格式化
  7. DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
  8. DateTimePickerMode pickerMode: DateTimePickerMode.date,
  9. //显示的类型: date(日期选择器)、time(时间选择器)、datetime(日期时间选择器)
  10. DateTimePickerTheme pickerTheme: DatePickerTheme.Default, //样式
  11. DateVoidCallback onCancel, //点击标题取消按钮的回调事件
  12. DateVoidCallback onClose, //关闭日期时间选择器的回调事件
  13. DateValueCallback onChange, //选择的日期时间改变的事件
  14. DateValueCallback onConfirm, //点击标题确定按钮的回调事件
  15. });

日期选择器

image.png

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  4. class DatePickerDemo extends StatefulWidget {
  5. @override
  6. _DatePickerDemoState createState() => _DatePickerDemoState();
  7. }
  8. class _DatePickerDemoState extends State<DatePickerDemo> {
  9. static final now = DateTime.now();
  10. DateTime _date = now;
  11. _showDatePicker() {
  12. DatePicker.showDatePicker(
  13. context,
  14. minDateTime: now.subtract(Duration(days: 365)),
  15. maxDateTime: DateTime.parse('2021-11-13'),
  16. initialDateTime: _date,
  17. dateFormat: 'yyyy-MM-dd',
  18. locale: DateTimePickerLocale.zh_cn,
  19. onCancel: () {
  20. print('onCancel');
  21. },
  22. onConfirm: (dateTime, List<int> index) {
  23. setState(() {
  24. _date = dateTime;
  25. });
  26. },
  27. );
  28. }
  29. @override
  30. Widget build(BuildContext context) {
  31. return Container(
  32. child: Column(
  33. children: [
  34. InkWell(
  35. child: Row(
  36. children: [
  37. Text(formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']), textScaleFactor: 2),
  38. Icon(Icons.arrow_drop_down),
  39. ],
  40. ),
  41. onTap: _showDatePicker,
  42. ),
  43. ],
  44. ),
  45. );
  46. }
  47. }

时间选择器

image.png

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  4. class DatePickerDemo extends StatefulWidget {
  5. @override
  6. _DatePickerDemoState createState() => _DatePickerDemoState();
  7. }
  8. class _DatePickerDemoState extends State<DatePickerDemo> {
  9. static final now = DateTime.now();
  10. DateTime _time = now;
  11. _showTimePicker() {
  12. DatePicker.showDatePicker(
  13. context,
  14. // minDateTime: now.subtract(Duration(days: 30)),
  15. // maxDateTime: DateTime.parse('2021-11-25 22:45:10'),
  16. initialDateTime: _time,
  17. dateFormat: 'HH:mm:ss',
  18. pickerMode: DateTimePickerMode.time,
  19. onConfirm: (dateTime, List<int> index) {
  20. setState(() {
  21. _time = dateTime;
  22. });
  23. },
  24. );
  25. }
  26. @override
  27. Widget build(BuildContext context) {
  28. return InkWell(
  29. child: Row(
  30. children: [
  31. Text(formatDate(_time, [HH, ':', nn, ':', ss]), textScaleFactor: 2),
  32. Icon(Icons.arrow_drop_down),
  33. ],
  34. ),
  35. onTap: _showTimePicker,
  36. );
  37. }
  38. }

日期时间选择器

image.png

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  4. class DatePickerDemo extends StatefulWidget {
  5. @override
  6. _DatePickerDemoState createState() => _DatePickerDemoState();
  7. }
  8. class _DatePickerDemoState extends State<DatePickerDemo> {
  9. static final now = DateTime.now();
  10. DateTime _datetime = now;
  11. _showDateTimePicker() {
  12. DatePicker.showDatePicker(
  13. context,
  14. // minDateTime: now.subtract(Duration(days: 30)),
  15. // maxDateTime: DateTime.parse('2021-11-25 22:45:10'),
  16. initialDateTime: _datetime,
  17. dateFormat: 'yyyy年MM月dd日 HH:mm',
  18. pickerMode: DateTimePickerMode.datetime,
  19. onConfirm: (dateTime, List<int> index) {
  20. setState(() {
  21. _datetime = dateTime;
  22. });
  23. },
  24. );
  25. }
  26. @override
  27. Widget build(BuildContext context) {
  28. return InkWell(
  29. child: Row(
  30. children: [
  31. Text(
  32. formatDate(_datetime, [yyyy, '年', mm, '月', dd, '日 ', HH, ':', nn]),
  33. textScaleFactor: 2
  34. ),
  35. Icon(Icons.arrow_drop_down),
  36. ],
  37. ),
  38. onTap: _showDateTimePicker,
  39. );
  40. }
  41. }

内联控件(直接显示在页面上)

DatePickerWidget

  1. DatePickerWidget({
  2. DateTime minDateTime, //最小值
  3. DateTime maxDateTime, //最大值
  4. DateTime initialDateTime, //初始值
  5. String dateFormat: DATETIME_PICKER_DATE_FORMAT, //格式化
  6. DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
  7. DateTimePickerTheme pickerTheme: DatePickerTheme.Default, //样式
  8. DateVoidCallback onCancel,
  9. DateValueCallback onChange,
  10. DateValueCallback onConfirm,
  11. })

示例

fds.gif

  1. import 'package:flutter/material.dart';
  2. import 'package:date_format/date_format.dart';
  3. import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
  4. class DatePickerDemo extends StatefulWidget {
  5. @override
  6. _DatePickerDemoState createState() => _DatePickerDemoState();
  7. }
  8. class _DatePickerDemoState extends State<DatePickerDemo> {
  9. static final now = DateTime.now();
  10. DateTime _date = now;
  11. @override
  12. Widget build(BuildContext context) {
  13. return Container(
  14. child: Column(
  15. children: [
  16. InkWell(
  17. child: Row(
  18. children: [
  19. Text(formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']), textScaleFactor: 2),
  20. Icon(Icons.arrow_drop_down),
  21. ],
  22. ),
  23. onTap: _showDatePicker,
  24. ),
  25. DatePickerWidget(
  26. minDateTime: now.subtract(Duration(days: 180)),
  27. maxDateTime: DateTime.parse('2021-11-13'),
  28. initialDateTime: _date,
  29. dateFormat: 'yyyy-MM-dd',
  30. locale: DateTimePickerLocale.zh_cn,
  31. onCancel: () {
  32. print('onCancel');
  33. },
  34. onChange: (dateTime, List<int> index) {
  35. setState(() {
  36. _date = dateTime;
  37. });
  38. },
  39. ),
  40. ],
  41. ),
  42. );
  43. }
  44. }


TimePickerWidget

  1. TimePickerWidget({
  2. DateTime minDateTime, //最小值
  3. DateTime maxDateTime, //最大值
  4. DateTime initialDateTime, //初始值
  5. String dateFormat: DATETIME_PICKER_DATE_FORMAT, //格式化
  6. DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
  7. DateTimePickerTheme pickerTheme: DatePickerTheme.Default,
  8. int minuteDivider: 1, //[int] minute restriction, e.g. 5: every 5th minute will be shown (0, 5, 10, 15 ...)
  9. DateVoidCallback onCancel,
  10. DateValueCallback onChange,
  11. DateValueCallback onConfirm,
  12. })


DateTimePickerWidget

  1. DateTimePickerWidget({
  2. DateTime minDateTime,
  3. DateTime maxDateTime,
  4. DateTime initialDateTime,
  5. String dateFormat: DATETIME_PICKER_DATE_FORMAT,
  6. DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT,
  7. DateTimePickerTheme pickerTheme: DatePickerTheme.Default,
  8. DateVoidCallback onCancel,
  9. DateValueCallback onChange,
  10. DateValueCallback onConfirm,
  11. })


DateTimePickerLocale 国际化

多语言支持:

  • enus: 美式英语 [Default locale]_
  • ar: 阿拉伯语
  • ar_eg: 阿拉伯语(埃及)
  • bn: 孟加拉语
  • bs: 波斯尼亚语
  • de: 德语
  • es: 西班牙语
  • fr: 法语
  • hr: 克罗地亚语
  • hu: 匈牙利语
  • in_id: 印尼语
  • it: 意大利语
  • jp: 日语
  • ko: 韩语
  • nl: 荷兰语
  • pt_br: 葡萄牙语(巴西)
  • ro: 罗马尼亚语
  • ru: 俄语
  • sr_cyrl: 塞尔维亚(西里尔)
  • sr_latn: 塞尔维亚(拉丁文)
  • tr: 土耳其语
  • uk: 乌克兰语
  • vi: 越南语
  • zh_cn: 简体中文

添加更多的语言

1. 添加语言文件

Fork 该项目, 在 lib/src/i18n/ 文件夹中添加语言文件。参考 strings_en_us.dart 文件。

  1. /// English (EN) United States
  2. class _StringsEnUs extends _StringsI18n {
  3. const _StringsEnUs();
  4. @override
  5. String getCancelText() {
  6. // TODO 返回标题栏取消按钮的显示文字
  7. return null;
  8. }
  9. @override
  10. String getDoneText() {
  11. // TODO 返回标题栏确定按钮的显示文字
  12. return null;
  13. }
  14. @override
  15. List<String> getMonths() {
  16. // TODO 返回月份的全称 [1月, 2月 ... 12月]
  17. return null;
  18. }
  19. @override
  20. List<String> getMonthsShort() {
  21. // TODO 返回月份的简称 [Jan, Feb ... Dec],返回null默认对全程进行截取,最多截取3位
  22. return null;
  23. }
  24. @override
  25. List<String> getWeeksFull() {
  26. // TODO 返回星期几的全称 [周一, 周二 ... 周日]
  27. return null;
  28. }
  29. @override
  30. List<String> getWeeksShort() {
  31. // TODO 返回星期几的缩写 [周一, 周二 ... 周日]
  32. return null;
  33. }
  34. }

2. 添加 DateTimePickerLocale

lib/src/i18n/date_picker_i18n.dart 文件中添加新语言对应的 DateTimePickerLocale

  1. enum DateTimePickerLocale {
  2. /// English (EN) United States
  3. en_us,
  4. }

3. 添加 DateTimePickerLocale 和语言的对应关系

lib/src/i18n/date_picker_i18n.dart 文件中添加 DateTimePickerLocale 和语言的对应关系。

  1. const Map<DateTimePickerLocale, _StringsI18n> datePickerI18n = {
  2. DateTimePickerLocale.en_us: const _StringsEnUs(),
  3. };