https://api.flutter.dev/flutter/material/showDatePicker.html
在 Flutter 里没有对应的组件,而是提供两个函数:showDatePicker() 和 showTimePicker()。
showDatePicker 官方日期组件
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static DateTime now = DateTime.now();
DateTime _date = now;
_openDate() {
showDatePicker(
context: context,
initialDate: _date, //初始化日期(选中日期),组件上会高亮背景标识
currentDate: now, //当前日期(一般设为今天,组件上会用 幽灵按钮样式圈中)
firstDate: now.subtract(Duration(days: 30)), //起始日期,超出范围后不能选择
lastDate: now.add(Duration(days: 30)), //终止日期
initialEntryMode: DatePickerEntryMode.calendar, //calendar 默认; input 只可以输入,不能选择
helpText: '帮助', //顶部帮助信息
cancelText: '取消', //置换cancel按钮文本
confirmText: '确定', //置换ok按钮文本
// useRootNavigator: false, //是否显示导航指示信息,默认为true
).then((v) {
setState(() {
_date = (v ?? _date);
});
});
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
InkWell(
child: Row(
children: [
Text(formatDate(_date, [yyyy, '-', mm, '-', dd]), textScaleFactor: 3),
Icon(Icons.arrow_drop_down),
],
),
onTap: this._openDate,
),
],
),
);
}
}
showTimePicker 官方时间组件
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static var now = DateTime.now();
static var nowTime = TimeOfDay.fromDateTime(now);
TimeOfDay _time = nowTime;
_openTime() {
showTimePicker(
context: context,
initialTime: _time,
initialEntryMode: TimePickerEntryMode.dial, //dial input
).then((v) {
setState(() {
_time = (v ?? _time);
});
});
}
@override
Widget build(BuildContext context) {
return InkWell(
child: Row(
children: [
Text(_time.format(context), textScaleFactor: 3),
Icon(Icons.arrow_drop_down),
],
),
onTap: this._openTime,
);
}
}
汉化
https://flutterchina.club/tutorials/internationalization/
https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html
(1)配置 flutter_localizations 依赖
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
(2)导入flutter_localizations库,并指定MaterialApp的localizationsDelegates
和upportedLocales
。
import "package:flutter/material.dart";
import 'package:flutter_localizations/flutter_localizations.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//...
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('zh', 'CH'), // China
// ... other locales the app supports
],
);
}
}
(3)要显示中文的控件设置:
如果手机系统是中文的话,showDatePicker就不需要再导入 locale: Locale('zh')
了。
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart' as DateFormat;
//date_format库和flutter_localizations的库 Localel类 冲突
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static var now = DateTime.now();
DateTime _date = now;
_openDate() {
showDatePicker(
context: context,
initialDate: _date,
currentDate: now,
firstDate: now.subtract(Duration(days: 30)),
lastDate: now.add(Duration(days: 30)),
locale: Locale('zh'),
).then((v) {
setState(() {
_date = (v ?? _date);
});
});
}
@override
Widget build(BuildContext context) {
return InkWell(
child: Row(
children: [
Text(
DateFormat.formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']),
textScaleFactor: 3
),
Icon(Icons.arrow_drop_down),
],
),
onTap: this._openDate,
);
}
}
库 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
文件中添加依赖:
dependencies:
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
dependencies:
flutter:
sdk: flutter
flutter_cupertino_date_picker:
git:
url: https://github.com/imshashank/flutter-cupertino-date-picker # Repo
ref: master # Branch name
2. 获取包
执行 Flutter 的命令获取包资源:
$ flutter packages get
3. 导入控件
在项目中导入该控件:
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, 日期时间选择器的样式
const DateTimePickerTheme({
this.backgroundColor: DATETIME_PICKER_BACKGROUND_COLOR, //背景色
this.cancelTextStyle, //默认标题栏取消按钮的样式 [TextStyle]
this.confirmTextStyle, //默认标题栏确定按钮的样式 [TextStyle]
this.cancel, //自定义标题栏取消按钮
this.confirm, //自定义标题栏确定按钮
this.title, //自定义标题栏。如果指定了自定义标题栏,不显示默认的标题栏。
//指定自定义的标题栏时必须指定 [titleHeight] 的值
this.showTitle: DATETIME_PICKER_SHOW_TITLE_DEFAULT,
//是否显示默认的标题栏。如果设置为false,默认的取消、确定按钮都不会显示,自定义的标题栏不受影响
this.pickerHeight: DATETIME_PICKER_HEIGHT, //日期选择器的高度
this.titleHeight: DATETIME_PICKER_TITLE_HEIGHT, //标题栏的高度
this.itemHeight: DATETIME_PICKER_ITEM_HEIGHT, //选择器每一行的高度
this.itemTextStyle: DATETIME_PICKER_ITEM_TEXT_STYLE, //选择器每一行的样式 [TextStyle]
});
DatePicker方法,BottomSheet形式(底部滑出)
DatePicker.showDatePicker(
BuildContext context,
DateTime minDateTime, //最小值
DateTime maxDateTime, //最大值
DateTime initialDateTime, //初始值
String dateFormat, //格式化
DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
DateTimePickerMode pickerMode: DateTimePickerMode.date,
//显示的类型: date(日期选择器)、time(时间选择器)、datetime(日期时间选择器)
DateTimePickerTheme pickerTheme: DatePickerTheme.Default, //样式
DateVoidCallback onCancel, //点击标题取消按钮的回调事件
DateVoidCallback onClose, //关闭日期时间选择器的回调事件
DateValueCallback onChange, //选择的日期时间改变的事件
DateValueCallback onConfirm, //点击标题确定按钮的回调事件
});
日期选择器
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static final now = DateTime.now();
DateTime _date = now;
_showDatePicker() {
DatePicker.showDatePicker(
context,
minDateTime: now.subtract(Duration(days: 365)),
maxDateTime: DateTime.parse('2021-11-13'),
initialDateTime: _date,
dateFormat: 'yyyy-MM-dd',
locale: DateTimePickerLocale.zh_cn,
onCancel: () {
print('onCancel');
},
onConfirm: (dateTime, List<int> index) {
setState(() {
_date = dateTime;
});
},
);
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
InkWell(
child: Row(
children: [
Text(formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']), textScaleFactor: 2),
Icon(Icons.arrow_drop_down),
],
),
onTap: _showDatePicker,
),
],
),
);
}
}
时间选择器
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static final now = DateTime.now();
DateTime _time = now;
_showTimePicker() {
DatePicker.showDatePicker(
context,
// minDateTime: now.subtract(Duration(days: 30)),
// maxDateTime: DateTime.parse('2021-11-25 22:45:10'),
initialDateTime: _time,
dateFormat: 'HH:mm:ss',
pickerMode: DateTimePickerMode.time,
onConfirm: (dateTime, List<int> index) {
setState(() {
_time = dateTime;
});
},
);
}
@override
Widget build(BuildContext context) {
return InkWell(
child: Row(
children: [
Text(formatDate(_time, [HH, ':', nn, ':', ss]), textScaleFactor: 2),
Icon(Icons.arrow_drop_down),
],
),
onTap: _showTimePicker,
);
}
}
日期时间选择器
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static final now = DateTime.now();
DateTime _datetime = now;
_showDateTimePicker() {
DatePicker.showDatePicker(
context,
// minDateTime: now.subtract(Duration(days: 30)),
// maxDateTime: DateTime.parse('2021-11-25 22:45:10'),
initialDateTime: _datetime,
dateFormat: 'yyyy年MM月dd日 HH:mm',
pickerMode: DateTimePickerMode.datetime,
onConfirm: (dateTime, List<int> index) {
setState(() {
_datetime = dateTime;
});
},
);
}
@override
Widget build(BuildContext context) {
return InkWell(
child: Row(
children: [
Text(
formatDate(_datetime, [yyyy, '年', mm, '月', dd, '日 ', HH, ':', nn]),
textScaleFactor: 2
),
Icon(Icons.arrow_drop_down),
],
),
onTap: _showDateTimePicker,
);
}
}
内联控件(直接显示在页面上)
DatePickerWidget
DatePickerWidget({
DateTime minDateTime, //最小值
DateTime maxDateTime, //最大值
DateTime initialDateTime, //初始值
String dateFormat: DATETIME_PICKER_DATE_FORMAT, //格式化
DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
DateTimePickerTheme pickerTheme: DatePickerTheme.Default, //样式
DateVoidCallback onCancel,
DateValueCallback onChange,
DateValueCallback onConfirm,
})
示例
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
class DatePickerDemo extends StatefulWidget {
@override
_DatePickerDemoState createState() => _DatePickerDemoState();
}
class _DatePickerDemoState extends State<DatePickerDemo> {
static final now = DateTime.now();
DateTime _date = now;
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
InkWell(
child: Row(
children: [
Text(formatDate(_date, ['yyyy', '-', 'mm', '-', 'dd']), textScaleFactor: 2),
Icon(Icons.arrow_drop_down),
],
),
onTap: _showDatePicker,
),
DatePickerWidget(
minDateTime: now.subtract(Duration(days: 180)),
maxDateTime: DateTime.parse('2021-11-13'),
initialDateTime: _date,
dateFormat: 'yyyy-MM-dd',
locale: DateTimePickerLocale.zh_cn,
onCancel: () {
print('onCancel');
},
onChange: (dateTime, List<int> index) {
setState(() {
_date = dateTime;
});
},
),
],
),
);
}
}
TimePickerWidget
TimePickerWidget({
DateTime minDateTime, //最小值
DateTime maxDateTime, //最大值
DateTime initialDateTime, //初始值
String dateFormat: DATETIME_PICKER_DATE_FORMAT, //格式化
DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT, //国际化
DateTimePickerTheme pickerTheme: DatePickerTheme.Default,
int minuteDivider: 1, //[int] minute restriction, e.g. 5: every 5th minute will be shown (0, 5, 10, 15 ...)
DateVoidCallback onCancel,
DateValueCallback onChange,
DateValueCallback onConfirm,
})
DateTimePickerWidget
DateTimePickerWidget({
DateTime minDateTime,
DateTime maxDateTime,
DateTime initialDateTime,
String dateFormat: DATETIME_PICKER_DATE_FORMAT,
DateTimePickerLocale locale: DATETIME_PICKER_LOCALE_DEFAULT,
DateTimePickerTheme pickerTheme: DatePickerTheme.Default,
DateVoidCallback onCancel,
DateValueCallback onChange,
DateValueCallback onConfirm,
})
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
文件。
/// English (EN) United States
class _StringsEnUs extends _StringsI18n {
const _StringsEnUs();
@override
String getCancelText() {
// TODO 返回标题栏取消按钮的显示文字
return null;
}
@override
String getDoneText() {
// TODO 返回标题栏确定按钮的显示文字
return null;
}
@override
List<String> getMonths() {
// TODO 返回月份的全称 [1月, 2月 ... 12月]
return null;
}
@override
List<String> getMonthsShort() {
// TODO 返回月份的简称 [Jan, Feb ... Dec],返回null默认对全程进行截取,最多截取3位
return null;
}
@override
List<String> getWeeksFull() {
// TODO 返回星期几的全称 [周一, 周二 ... 周日]
return null;
}
@override
List<String> getWeeksShort() {
// TODO 返回星期几的缩写 [周一, 周二 ... 周日]
return null;
}
}
2. 添加 DateTimePickerLocale
在 lib/src/i18n/date_picker_i18n.dart
文件中添加新语言对应的 DateTimePickerLocale
。
enum DateTimePickerLocale {
/// English (EN) United States
en_us,
}
3. 添加 DateTimePickerLocale 和语言的对应关系
在 lib/src/i18n/date_picker_i18n.dart
文件中添加 DateTimePickerLocale 和语言的对应关系。
const Map<DateTimePickerLocale, _StringsI18n> datePickerI18n = {
DateTimePickerLocale.en_us: const _StringsEnUs(),
};