今天我们来聊聊Flutter中的日期和日期选择器。

Flutter中的日期和时间戳

//日期时间戳转换
var _nowTime = DateTime.now();//获取当前时间
print(_nowTime);
print(_nowDate.millisecondsSinceEpoch); //13位时间戳 1575389234667
print(DateTime.fromMillisecondsSinceEpoch(1575389234667)); //时间戳转为日期2019-12-03 16:07:14.667

展示一个时间,会有多种形式,比如1970-01-01、1970/01/01、1970年01月01日,等等,那么我们如何把同一个时间根据需要转换成不同的格式呢?接下来我就为大家介绍一个Flutter中的第三方库。

Flutter的第三方库 date_format 

地址:https://pub.dev/packages/date_format

添加依赖:date_format: ^1.0.8 

引入:

import 'package:date_format/date_format.dart';

简单来个例子,代码如下:

print(formatDate(DateTime.now(), [yyyy, "年", mm, "月", dd])); //2019年12月03

在开发项目的时候,我们经常会遇到选择时间或者选择日期的场景,接下来我将为大家介绍Flutter中自带的日期选择器和时间选择器。

调用Flutter自带的日期选择器组件和时间选择器组件

调起日期选择器的方法showDatePicker的返回值是Future,Future是一个异步类型,因此showDatePicker是一个异步方法。而要获取异步方法里面的数据,有两种方式。

1、获取异步方法里面的值的第一种方式:then

_showDatePicker(){
    showDatePicker(
      context: context,
      initialDate: _nowDate, //选中的日期
      firstDate: DateTime(1900), //日期选择器上可选择的最早日期
      lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
    ).then((result){
      print(result);
    });
 }

2、获取异步方法里面的值的第二种方式:async+await

_showDatePicker() async{
    var result = await showDatePicker(
      context: context,
      initialDate: _nowDate, //选中的日期
      firstDate: DateTime(1900), //日期选择器上可选择的最早日期
      lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
    );
    print(result);
  }

两种方式都可以实现调用日期选择器。

Flutter自带的日期选择器是showDatePicker,时间选择器是showTimePicker。这两个选择器默认的显示效果都是英文的,我们是在中国,那么就需要将其显示成中文版的,这就涉及到Flutter的国际化的问题。

Flutter中的国际化

第一步:配置flutter_localizations依赖

找到pubspec.yaml,配置flutter_localizations:

flutter_localizations:
    sdk: flutter

第二步:导入国际化的包flutter_localizations.dart

main.dart导入

import 'package:flutter_localizations/flutter_localizations.dart';

第三步,设置国际化

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;
      }
    });
  });
}

这样配置好了之后,效果如下:

android studio查看flutter的print打印 flutter dateformat_选择器

完整代码如下:

import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';

class DatePicker extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DatePicker();
}

class _DatePicker extends State<DatePicker> {
  DateTime _nowDate = DateTime.now(); //当前日期
  TimeOfDay _nowTime = TimeOfDay.now(); //当前时间

  //调起日期选择器
  _showDatePicker(){
    //获取异步方法里面的值的第一种方式:then
    showDatePicker(
      //如下四个参数为必填参数
      context: context,
      initialDate: _nowDate, //选中的日期
      firstDate: DateTime(1900), //日期选择器上可选择的最早日期
      lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
    ).then((result){
      print(result);
      //将选中的值传递出来
      setState(() {
        this._nowDate = result;
      });
    });
  }
  // _showDatePicker() async{
  //   // 获取异步方法里面的值的第二种方式:async+await
  //   //await的作用是等待异步方法showDatePicker执行完毕之后获取返回值
  //   var result = await showDatePicker(
  //     context: context,
  //     initialDate: _nowDate, //选中的日期
  //     firstDate: DateTime(1900), //日期选择器上可选择的最早日期
  //     lastDate: DateTime(2100), //日期选择器上可选择的最晚日期
  //   );
  //   print(result);
  //   setState(() {
  //     this._nowDate = result;
  //   });
  // }

  //调起时间选择器
  _showTimePicker() async{
    // 获取异步方法里面的值的第二种方式:async+await
    //await的作用是等待异步方法showDatePicker执行完毕之后获取返回值
    var result = await showTimePicker(
      context: context,
      initialTime: _nowTime, //选中的时间
    );
    print(result);
    //将选中的值传递出来
    setState(() {
      this._nowTime = result;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    var _date = formatDate(_nowDate, [yyyy, "-", mm, "-", dd]);
    var _time = _nowTime.format(context);  
    return Scaffold(
      appBar: AppBar(title: Text("日期时间选择器")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              InkWell(
                onTap:_showDatePicker,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text("${_date}"),
                    Icon(Icons.arrow_drop_down)
                  ],
                ),
              ),
              InkWell(
                onTap:_showTimePicker,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text("${_time}"),
                    Icon(Icons.arrow_drop_down)
                  ],
                ),
              ),
            ],
          )
        ],
      ),

    );
  }
}

调用Flutter的第三方时间选择器组件 

上面介绍了系统给我们提供的日期时间选择器,但是有时候系统提供的选择器并不符合我们的要求,这时我们就可以到pub.dev上去寻找符合我们要求的日期选择器。

这里我们介绍一款Cupertino风格(即iOS风格)的日期选择器——flutter_cupertino_date_picker。

地址:https://pub.dev/packages/flutter_cupertino_date_picker

添加依赖:flutter_cupertino_date_picker: ^1.0.12

新建dart页面,引入:

import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';

这个插件提供了很多种格式,看你需要那种格式就找到那种格式的例子代码,看怎么使用。

1、首先date_picker_bottom_sheet为例

地址:https://github.com/dylanwuzh/flutter-cupertino-date-picker/blob/master/example/lib/date_picker_bottom_sheet.dart

一些引入date_format包,当前日期等参数我就不再写了。见上面代码

调起date_picker_bottom选择器,为了和上面的代码区分,我换了一个名字

//调起date_picker_bottom选择器
  _cupertinoPicker(){
    DatePicker.showDatePicker(
      context,
      pickerTheme: DateTimePickerTheme(
        showTitle: true,
        confirm: Text('确定', style: TextStyle(color: Colors.red)), 
        cancel: Text('取消', style: TextStyle(color: Colors.cyan)),
      ),
      minDateTime: DateTime.parse('2010-05-12'), //起始日期
      maxDateTime: DateTime.parse('2021-11-25'), //终止日期
      initialDateTime: _nowDate, //当前日期
      dateFormat: 'yyyy-MMMM-dd',  //显示格式
      locale: DateTimePickerLocale.zh_cn, //语言 默认DateTimePickerLocale.en_us
      onClose: () => print("----- onClose -----"),
      onCancel: () => print('onCancel'),
      onChange: (dateTime, List<int> index) { //改变的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
      onConfirm: (dateTime, List<int> index) { //确定的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
    );
  }

效果图:

android studio查看flutter的print打印 flutter dateformat_flutter_02

完整代码如下:

import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';

class CupertinoTimePage extends StatefulWidget {
  CupertinoTimePage({Key key}) : super(key: key);

  @override
  _CupertinoTimePageState createState() => _CupertinoTimePageState();
}

class _CupertinoTimePageState extends State<CupertinoTimePage> {
  DateTime _nowDate = DateTime.now(); //当前日期
  TimeOfDay _nowTime = TimeOfDay.now(); //当前时间

  //调起flutter_cupertino_date_picker选择器
  _cupertinoPicker(){
    DatePicker.showDatePicker(
      context,
      pickerTheme: DateTimePickerTheme(
        showTitle: true,
        confirm: Text('确定', style: TextStyle(color: Colors.red)), 
        cancel: Text('取消', style: TextStyle(color: Colors.cyan)),
      ),
      minDateTime: DateTime.parse('2010-05-12'), //起始日期
      maxDateTime: DateTime.parse('2021-11-25'), //终止日期
      initialDateTime: _nowDate, //当前日期
      dateFormat: 'yyyy-MMMM-dd',  //显示格式
      locale: DateTimePickerLocale.zh_cn, //语言 默认DateTimePickerLocale.en_us
      onClose: () => print("----- onClose -----"),
      onCancel: () => print('onCancel'),
      onChange: (dateTime, List<int> index) { //改变的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
      onConfirm: (dateTime, List<int> index) { //确定的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    var _date = formatDate(_nowDate, [yyyy, "-", mm, "-", dd]);return Scaffold(
      appBar: AppBar(title: Text("第三方IOS时间选择器演示页面")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              InkWell(
                onTap: _cupertinoPicker,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text("${_date}"),
                    Icon(Icons.arrow_drop_down)
                  ],
                ),
              ),
            ]
          ),
        ]
      )        
    );
  }
}

datetime_picker_bottom_sheet

地址:https://github.com/dylanwuzh/flutter-cupertino-date-picker/blob/master/example/lib/datetime_picker_bottom_sheet.dart

调起datetime_picker_bottom选择器

//调起datetime_picker_bottom选择器
  _cupertinoDateTimePicker(){
    DatePicker.showDatePicker(
      context,
      minDateTime: DateTime.parse('2010-05-12'), //起始日期
      maxDateTime: DateTime.parse('2021-11-25'), //终止日期
      initialDateTime: DateTime.parse(formatDate(_selectedDateTime, [yyyy, "-", mm, "-", "dd", " ", HH, ":", nn, ":", ss])), //当前日期时间
      dateFormat: "yyyy年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(() {
          _nowDate = dateTime;
        });
      },
      onConfirm: (dateTime, List<int> index) {
        setState(() {
          _nowDate = dateTime;
        });
      },
    );
  }

效果图:

android studio查看flutter的print打印 flutter dateformat_选择器_03

完整代码:

import 'package:flutter/material.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';

class CupertinoTimePage extends StatefulWidget {
  CupertinoTimePage({Key key}) : super(key: key);

  @override
  _CupertinoTimePageState createState() => _CupertinoTimePageState();
}

class _CupertinoTimePageState extends State<CupertinoTimePage> {
  DateTime _nowDate = DateTime.now(); //当前日期
  DateTime _nowDateTime = DateTime.parse(formatDate(DateTime.now(), [yyyy, "-", mm, "-", "dd", " ", HH, ":", nn, ":", ss])); //当前日期时间

  //调起date_picker_bottom选择器
  _cupertinoPicker(){
    DatePicker.showDatePicker(
      context,
      pickerTheme: DateTimePickerTheme(
        showTitle: true,
        confirm: Text('确定', style: TextStyle(color: Colors.red)), 
        cancel: Text('取消', style: TextStyle(color: Colors.cyan)),
      ),
      minDateTime: DateTime.parse('2010-05-12'), //起始日期
      maxDateTime: DateTime.parse('2021-11-25'), //终止日期
      initialDateTime: _nowDate, //当前日期
      dateFormat: 'yyyy-MMMM-dd',  //显示格式
      locale: DateTimePickerLocale.zh_cn, //语言 默认DateTimePickerLocale.en_us
      onClose: () => print("----- onClose -----"),
      onCancel: () => print('onCancel'),
      onChange: (dateTime, List<int> index) { //改变的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
      onConfirm: (dateTime, List<int> index) { //确定的时候
        setState(() {
          _nowDate = dateTime;
        });
      },
    );
  }

  //调起datetime_picker_bottom选择器
  _cupertinoDateTimePicker(){
    DatePicker.showDatePicker(
      context,
      minDateTime: DateTime.parse('2010-05-12'), //起始日期
      maxDateTime: DateTime.parse('2021-11-25'), //终止日期
      //initialDateTime: DateTime.parse(formatDate(_selectedDateTime, [yyyy, "-", mm, "-", "dd", " ", HH, ":", nn, ":", ss])),
      initialDateTime: _nowDateTime, //当前日期时间
      dateFormat: "yyyy年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(() {
          _nowDate = dateTime;
        });
      },
      onConfirm: (dateTime, List<int> index) {
        setState(() {
          _nowDate = dateTime;
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    var _date = formatDate(_nowDate, [yyyy, "-", mm, "-", dd]);
    var _datetime = formatDate(_nowDate,[yyyy, "-", mm, "-", dd, " ", HH, ":", nn]);
    return Scaffold(
      appBar: AppBar(title: Text("第三方IOS时间选择器演示页面")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              InkWell(
                onTap: _cupertinoPicker,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text("${_date}"),
                    Icon(Icons.arrow_drop_down)
                  ],
                ),
              ),
            ]
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              InkWell(
                onTap: _cupertinoDateTimePicker,
                child: Row(
                  children: <Widget>[
                    Text('${_datetime}'),
                    Icon(Icons.arrow_drop_down)
                  ],
                ),
              )
            ],
          )
        ]
      )        
    );
  }
}