今天我们来聊聊Flutter中的日期和日期选择器。
Flutter中的日期和时间戳
使用代码如下:
//将时间转换成时间戳
var nowTime = DateTime.now();//获取当前时间
print(nowTime);//2019-08-28 13:45:17.890514
var a = nowTime.millisecondsSinceEpoch;//单位是毫秒(千分之一秒),13位时间戳
print(a);//1566971117890
//将时间戳转换成时间
var aTime = DateTime.fromMillisecondsSinceEpoch(a);
print(aTime);//2019-08-28 13:45:17.890
打印结果如下:
flutter: 2019-08-28 13:45:17.890514
flutter: 1566971117890
flutter: 2019-08-28 13:45:17.890
所谓时间戳,是指自格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
有些情况下,后台可能会将所有的时间都转换成时间戳返回给我们前端,这是我们就需要将时间戳转换成时间,并将时间进行格式化。
展示一个时间,我们会有多种形式,比如1970-01-01、1970/01/01、1970年01月01日,等等,那么我们如何把同一个时间根据需要转换成不同的格式呢?接下来我就为大家介绍一个Flutter中的第三方库。
Flutter的第三方库 date_format 的使用
实际上,我在之前介绍在Flutter中如何导入第三方库的文章依赖管理(二):第三方组件库在Flutter中要如何管理中,就是以date_format这个库为例子作讲解的。
在依赖管理(二):第三方组件库在Flutter中要如何管理中,我详细介绍了如何去查找第三方库、如何将pub.dev中的第三方库安装到Flutter项目中、date_format库的基本使用,这里我就不赘述了。
简单来个小例子吧,代码如下:
print(formatDate(DateTime.now(), [yyyy, "-", mm, "-", dd, " ", DD, " ", HH, ":", nn, ":", ss]));
打印结果如下:
2019-08-28 Wednesday 14:27:29
在开发项目的时候,我们经常会遇到选择时间或者选择日期的场景,接下来我将为大家介绍Flutter中自带的日期选择器和时间选择器。
调用Flutter自带的日期选择器组件和时间选择器组件
import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
class TimePickerPage extends StatefulWidget {
TimePickerPage({Key key}) : super(key: key);
_TimePickerPageState createState() => _TimePickerPageState();
}
class _TimePickerPageState extends State<TimePickerPage> {
DateTime _selectedDate = DateTime.now(); //当前选中的日期
TimeOfDay _selectedTime = TimeOfDay.now(); //当前选中的时间
@override
Widget build(BuildContext context) {
//调起日期选择器
_showDatePicker() {
//获取异步方法里面的值的第一种方式:then
showDatePicker(
//如下四个参数为必填参数
context: context,
initialDate: _selectedDate, //选中的日期
firstDate: DateTime(1980), //日期选择器上可选择的最早日期
lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
).then((selectedValue) {
setState(() {
//将选中的值传递出来
this._selectedDate = selectedValue;
});
});
}
//调起时间选择器
_showTimePicker() async {
// 获取异步方法里面的值的第二种方式:async+await
//await的作用是等待异步方法showDatePicker执行完毕之后获取返回值
var result = await showTimePicker(
context: context,
initialTime: _selectedTime, //选中的时间
);
//将选中的值传递出来
setState(() {
this._selectedTime = result;
});
}
return Scaffold(
appBar: AppBar(title: Text("时间选择器演示页面")),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//可以通过在外面包裹一层InkWell来让某组件可以响应用户事件
InkWell(
onTap: () {
//调起日期选择器
_showDatePicker();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(formatDate(
this._selectedDate, [yyyy, "-", mm, "-", "dd"])),
Icon(Icons.arrow_drop_down)
],
),
),
InkWell(
onTap: () {
//调起时间选择器
_showTimePicker();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("${this._selectedTime.format(context)}"),
Icon(Icons.arrow_drop_down)
],
),
)
],
)
],
),
);
}
}
效果如下:
关于上述代码,有以下几点需要说明。
1,调起日期选择器的方法showDatePicker的返回值是Future,Future是一个异步类型,因此showDatePicker是一个异步方法。而要获取异步方法里面的数据,有两种方式。
第一种方式是直接在异步方法的后面直接点语法调用then,如下:
//调起日期选择器
_showDatePicker() async {
//第一种方式:then
showDatePicker(
//如下四个参数为必填参数
context: context,
initialDate: _selectedDate, //选中的日期
firstDate: DateTime(1980), //日期选择器上可选择的最早日期
lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
).then((selectedValue) {
setState(() {
//将选中的值传递出来
this._selectedDate = selectedValue;
});
});
}
第二种方式是采取async+await的方式,如下:
//调起日期选择器
_showDatePicker() async {
// 第二种方式:async+await
//await的作用是等待异步方法showDatePicker执行完毕之后获取返回值
var result = await showDatePicker(
context: context,
initialDate: _selectedDate, //选中的日期
firstDate: DateTime(1980), //日期选择器上可选择的最早日期
lastDate: DateTime(2100),
);
//将选中的值传递出来
setState(() {
this._selectedDate = result;
});
}
2,我们如果想让某一个组件可以响应用户的点击事件,那么可以在该组件外面再包裹一层InkWell,如下所示:
//可以通过在外面包裹一层InkWell来让某组件可以响应用户事件
InkWell(
onTap: () {
//调起日期选择器
_showDatePicker();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(formatDate(
this._selectedDate, [yyyy, "-", mm, "-", "dd"])),
Icon(Icons.arrow_drop_down)
],
),
)
3,Flutter自带的日期选择器是showDatePicker,时间选择器是showTimePicker。这两个选择器默认的显示效果都是英文的,我们是在中国,那么就需要将其显示成中文版的,这就涉及到Flutter的国际化的问题。关于Flutter的国际化,接下来我将为大家做详细讲解。
Flutter中的国际化
Flutter中的日期选择器,默认是英文的,如下:
那么,如何将其改成中文展示呢?这就需要用到国际化配置。
在iOS和Android中,都有国际化配置的概念,Flutter中也不例外。在Flutter中如何配置国际化呢?
第一步:配置flutter_localizations依赖
找到pubspec.yaml,配置flutter_localizations
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
第二步:导入国际化的包flutter_localizations.dart
import 'package:flutter_localizations/flutter_localizations.dart';
第三步,设置国际化
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateRoute: prefix0.onGenerateRoute,
initialRoute: "/",
//配置如下两个国际化的参数
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: [
const Locale("zh", "CH"),
const Locale("en", "US")
],
);
}
}
第四步,在需要展示特定语言的组件中进行配置
//调起日期选择器
_showDatePicker() {
showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(1980),
lastDate: DateTime(2100),
locale: Locale("zh")//中文显示
).then((selectedValue) {
setState(() {
if (selectedValue != null) {
this._selectedDate = selectedValue;
}
});
});
}
这样配置好了之后,效果如下:
这里多说一句,关于Flutter的国际化,有一篇文章讲解的非常好,大家可以参考:https://www.jianshu.com/p/8356a3bc8f6c
调用Flutter的第三方时间选择器组件
上面我介绍了系统给我们提供的日期时间选择器,但是有时候系统提供的选择器并不符合我们的要求,这时我们就可以到pub.dev上去寻找符合我们要求的日期选择器。
这里我们介绍一款Cupertino风格(即iOS风格)的日期选择器——flutter_cupertino_date_picker。
使用代码如下:
import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
class TimePickerPage extends StatefulWidget {
TimePickerPage({Key key}) : super(key: key);
_TimePickerPageState createState() => _TimePickerPageState();
}
class _TimePickerPageState extends State<TimePickerPage> {
DateTime _selectedDateTime = DateTime.now();
@override
Widget build(BuildContext context) {
void _showDatePicker() {
DatePicker.showDatePicker(
context,
pickerTheme: DateTimePickerTheme(
showTitle: true,
confirm: Text('custom Done', style: TextStyle(color: Colors.red)),
cancel: Text('custom cancel', style: TextStyle(color: Colors.cyan)),
),
minDateTime: DateTime.parse("2010-05-12"), //选择器上可选择的最早时间
maxDateTime: DateTime.parse("2021-11-25"), //选择器上可选择的最晚时间
initialDateTime: _selectedDateTime, //选择器的当前选中时间
dateFormat: "yyyy-MMMM-dd", //时间格式
locale: DateTimePickerLocale.zh_cn, //国际化配置
onClose: () => print("----- onClose -----"),
onCancel: () => print('onCancel'),
onChange: (dateTime, List<int> index) {
setState(() {
_selectedDateTime = dateTime;
});
},
onConfirm: (dateTime, List<int> index) {
setState(() {
_selectedDateTime = dateTime;
});
},
);
}
/// Display time picker.
void _showDateTimePicker() {
DatePicker.showDatePicker(
context,
minDateTime: DateTime.parse("2019-05-15 09:23:10"),
maxDateTime: DateTime.parse("2020-06-03 21:11:00"),
initialDateTime: DateTime.parse(formatDate(_selectedDateTime, [yyyy, "-", mm, "-", "dd", " ", HH, ":", nn, ":", ss])),
dateFormat: "yy年M月d日 EEE,H时:m分",
locale: DateTimePickerLocale.zh_cn,
pickerTheme: DateTimePickerTheme(
showTitle: true,
),
pickerMode: DateTimePickerMode.datetime, // show TimePicker
onCancel: () {
debugPrint('onCancel');
},
onChange: (dateTime, List<int> index) {
setState(() {
_selectedDateTime = dateTime;
});
},
onConfirm: (dateTime, List<int> index) {
setState(() {
_selectedDateTime = dateTime;
});
},
);
}
return Scaffold(
appBar: AppBar(title: Text("时间选择器演示页面")),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
_showDatePicker();
},
child: Row(
children: <Widget>[
Text(formatDate(
_selectedDateTime, [yyyy, "-", mm, "-", dd])),
Icon(Icons.arrow_drop_down)
],
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
_showDateTimePicker();
},
child: Row(
children: <Widget>[
Text(formatDate(_selectedDateTime,
[yyyy, "-", mm, "-", dd, " ", HH, ":", nn])),
Icon(Icons.arrow_drop_down)
],
),
)
],
)
],
),
);
}
}
效果如下:
最后,关于第三方库的使用我想说的就是,多看看组件库里对该组件的介绍,实在不行就看看Demo。