Flutter入门(33):Flutter 组件之时间日期选择器(DatePicker,TimerPicker)详解

1. 基本介绍

showDatePicker、showTimePicker 是 flutter 提供的日期选择器弹框。
CalendarDatePicker 是替代 YearPicker、MonthPicker、DayPicker 的新的日期选择控件。
CupertinoDatePicker、CupertinoTimerPicker 是 iOS 风格的 DatePickerView 和 TimePickerView 的日期时间选择器。

2. 示例代码

代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。

3. 属性介绍

showDatePicker属性 介绍
context @required BuildContext,上下文 context
initialDate @required DateTime,日历初始化日期
2020-10-12 蓝色圆框.png
firstDate @required DateTime,日历开始日期
lastDate @required DateTime,日历结束日期
currentDate DateTime 当前日期
2020-10-20 蓝边圆圈.png
initialEntryMode DatePickerEntryMode.calendar 与 input 两种,分别为选择器和填写框
selectableDayPredicate (DateTime dayTime){ return true;} 一个返回 bool 值的函数,自定义哪些可选,下文会详解
helpText 左上角文字
helpText.png
cancelText 取消按钮文字
cancelText.png
confirmText 确认按钮文字,上图中 confirmText
locale 地区设置,以后多语言部分在详解
useRootNavigator 是否使用根导航,默认为 true,官方文档也没做详解,暂时没用到
routeSettings 路由设置,官方文档也没做详解,暂时没用到
textDirection 文字方向,TextDirection,DatePickerEntryMode.input 模式时,居左或者居右设置
builder 创建器,和直接创建基本一致,可以定制主题
initialDatePickerMode DatePickerMode.day 与 DatePickerMode.year 两种
errorFormatText 格式错误是下方提示
errorFormatText.png
fieldHintText 输入框默认提示语
fieldLabelText 输入框上方提示语
errorInvalidText 输入了不在 first 与 last 之间的日期提示语
errorInvalidText.png
showTimePicker属性 介绍
context @required BuildContext 上下文
initialTime @required TimeOfDay 设置默认日期
builder 创建器,和直接创建基本一致,可以定制主题
initialEntryMode 默认为 TimePickerEntryMode.dial。input 样式其实就是收起后的样子
helpText 左上角文字
helpText.png
cancelText 取消按钮文字
cancelText.png
confirmText 确认按钮文字,上图中 confirmText
useRootNavigator 是否使用根导航,默认为 true,官方文档也没做详解,暂时没用到
routeSettings 路由设置,官方文档也没做详解,暂时没用到
CalendarDatePicker属性 介绍
initialDate @required DateTime 初始化选中日期
firstDate @required DateTime 最小可选日期
lastDate @required DateTime 最大可选日期
currentDate DateTime 当前选中日期
onDateChanged @required 选中日期改变回调函数
onDisplayedMonthChanged 月份改变回调函数
initialCalendarMode DatePickerMode.day 日期选择器样式
selectableDayPredicate 筛选日期可不可点回调函数
CupertinoTimerPicker属性 介绍
mode 展示模式,默认为 CupertinoTimerPickerMode.hms
initialTimerDuration 默认选中事时间,默认为 Duration.zero
minuteInterval 分钟间隔

secondInterval 秒间隔
alignment | 对齐方式
backgroundColor | 背景颜色
onTimerDurationChanged | @required 滑动后,每次改变回调函数

CupertinoDatePicker属性 | 介绍
mode | 展示模式, 默认为 CupertinoDatePickerMode.dateAndTime,
onDateTimeChanged | @required 日期改变回调函数
initialDateTime | DateTime 默认选中日期
minimumDate | 最小可选日期
maximumDate | 最大可选日期
minimumYear | 最小可选年份
maximumYear | 最大可选年份
minuteInterval | 分钟间隔
use24hFormat | 是否使用24小时制
backgroundColor | 背景色

4. showDatePicker 详解

4.1 日期选择弹窗

import 'package:flutter/material.dart';

class FMDatePickerVC extends StatefulWidget{
  @override
  FMDatePickerState createState() => FMDatePickerState();
}

class FMDatePickerState extends State  {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          // _showDatePickerForYear(context),
          // _showDatePickerForInput(context),
        ],
      ),
    );
  }

  RaisedButton _showDatePicker(context){
    return RaisedButton(
      child: Text("showDatePicker"),
      onPressed: (){
        showDatePicker(
            context: context,
            initialDate: DateTime.now(), // 初始化选中日期
            firstDate: DateTime(2020, 6),  // 开始日期
            lastDate: DateTime(2021, 6),  // 结束日期
            // initialEntryMode: DatePickerEntryMode.input,  // 日历弹框样式

            textDirection: TextDirection.ltr,  // 文字方向

            currentDate: DateTime(2020, 10, 20),  // 当前日期
            helpText: "helpText", // 左上方提示
            cancelText: "cancelText",  // 取消按钮文案
            confirmText: "confirmText",  // 确认按钮文案

            errorFormatText: "errorFormatText",  // 格式错误提示
            errorInvalidText: "errorInvalidText",  // 输入不在 first 与 last 之间日期提示

            fieldLabelText: "fieldLabelText",  // 输入框上方提示
            fieldHintText: "fieldHintText",  // 输入框为空时内部提示

            initialDatePickerMode: DatePickerMode.day, // 日期选择模式,默认为天数选择
            useRootNavigator: true, // 是否为根导航器
            // 设置不可选日期,这里将 2020-10-15,2020-10-16,2020-10-17 三天设置不可选
            selectableDayPredicate: (dayTime){
              if(dayTime == DateTime(2020, 10, 15) || dayTime == DateTime(2020, 10, 16) || dayTime == DateTime(2020, 10, 17)) {
                return false;
              }
              return true;
            }
        );
      },
    );
  }
}
showDatePicker day.png

4.2 年份选择器

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
         //  _showDatePickerForInput(context),
        ],
      ),
    );
  }

  RaisedButton _showDatePickerForYear(context){
    return RaisedButton(
      child: Text("showDatePicker - YearMode"),
      onPressed: (){
        showDatePicker(
          context: context,
          initialDate: DateTime.now(), // 初始化选中日期
          firstDate: DateTime(2018, 6),  // 开始日期
          lastDate: DateTime(2025, 6),  // 结束日期
          currentDate: DateTime(2020, 10, 20),  // 当前日期
          helpText: "helpText", // 左上方提示
          cancelText: "cancelText",  // 取消按钮文案
          confirmText: "confirmText",  // 确认按钮文案

          initialDatePickerMode: DatePickerMode.year, // 日期选择模式,默认为天数选择
        );
      },
    );
  }
showDatePicker year.png

4.3 日期输入框

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
          _showDatePickerForInput(context),
        ],
      ),
    );
  }

  RaisedButton _showDatePickerForInput(context){
    return RaisedButton(
      child: Text("showDatePicker - InputMode"),
      onPressed: (){
        showDatePicker(
            context: context,
            initialDate: DateTime.now(), // 初始化选中日期
            firstDate: DateTime(2020, 6),  // 开始日期
            lastDate: DateTime(2021, 6),  // 结束日期
            initialEntryMode: DatePickerEntryMode.input,  // 日历弹框样式

            textDirection: TextDirection.ltr,  // 文字方向

            currentDate: DateTime(2020, 10, 20),  // 当前日期
            helpText: "helpText", // 左上方提示
            cancelText: "cancelText",  // 取消按钮文案
            confirmText: "confirmText",  // 确认按钮文案

            errorFormatText: "errorFormatText",  // 格式错误提示
            errorInvalidText: "errorInvalidText",  // 输入不在 first 与 last 之间日期提示

            fieldLabelText: "fieldLabelText",  // 输入框上方提示
            fieldHintText: "fieldHintText",  // 输入框为空时内部提示

            initialDatePickerMode: DatePickerMode.day, // 日期选择模式,默认为天数选择
            useRootNavigator: true, // 是否为根导航器
            // 设置不可选日期,这里将 2020-10-15,2020-10-16,2020-10-17 三天设置不可选
            selectableDayPredicate: (dayTime){
              if(dayTime == DateTime(2020, 10, 15) || dayTime == DateTime(2020, 10, 16) || dayTime == DateTime(2020, 10, 17)) {
                return false;
              }
              return true;
            }
        );
      },
    );
  }
showDatePicker input normal.png

showDatePicker input errorFormat.png

showDatePicker input errorInvalid.png

showDatePicker input rtl.png

4.4 日期选择器主题设置

主题 Theme 本身就是一个功能很庞大的东西,这里不多描述,有兴趣可以自行了解。

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
          _showDatePickerForInput(context),
          _showDatePickerForTheme(context),
        ],
      ),
    );
  }

  RaisedButton _showDatePickerForTheme(context){
    return RaisedButton(
      child: Text("showDatePicker - InputMode"),
      onPressed: (){
        showDatePicker(
            context: context,
            builder: (context, child) {
              return Theme(
                data: ThemeData(
                  cardColor: Colors.red,
                  brightness: Brightness.dark,
                ),
                child: child,
              );
            },
          initialDate: DateTime.now(), // 初始化选中日期
          firstDate: DateTime(2018, 6),  // 开始日期
          lastDate: DateTime(2025, 6),  // 结束日期
          currentDate: DateTime(2020, 10, 20),  // 当前日期
          helpText: "helpText", // 左上方提示
          cancelText: "cancelText",  // 取消按钮文案
          confirmText: "confirmText",  // 确认按钮文案

          initialDatePickerMode: DatePickerMode.year, // 日期选择模式,默认为天数选择
        );
      },
    );
  }
showDatePicker theme.png

5. showTimePicker 详解

和 showDatePicker 基本一样,不做赘述。

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
          _showDatePickerForInput(context),
          _showDatePickerForTheme(context),
          _showTimePicker(context),
        ],
      ),
    );
  }

  RaisedButton _showTimePicker(context){
    return RaisedButton(
      child: Text("showTimePicker - InputMode"),
      onPressed: (){
        showTimePicker(
          context: context,
          initialTime: TimeOfDay(hour: 10, minute: 30),
          cancelText: "cancelText",
          helpText: "helpText",
          confirmText: "confirmText"
        );
      },
    );
  }
showTimePicker dial.png

showTimePicker input.png

6. CalendarDatePicker 详解

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
          _showDatePickerForInput(context),
          _showDatePickerForTheme(context),
          _showTimePicker(context),
          Text("CalendarDatePicker day"),
          _calendarDatePicker(DatePickerMode.day),
          Text("CalendarDatePicker year"),
          _calendarDatePicker(DatePickerMode.year),
        ],
      ),
    );
  }

  CalendarDatePicker _calendarDatePicker(DatePickerMode mode){
    return CalendarDatePicker(
      initialDate: DateTime.now(), // 初始化选中日期
      currentDate: DateTime(2020, 10, 18),
      firstDate: DateTime(2020, 9, 10),  // 开始日期
      lastDate: DateTime(2022, 9, 10),  // 结束日期
      initialCalendarMode: mode, // 日期选择样式
      // 选中日期改变回调函数
      onDateChanged: (dateTime){
        print("onDateChanged $dateTime");
      },
      // 月份改变回调函数
      onDisplayedMonthChanged: (dateTime){
        print("onDisplayedMonthChanged $dateTime");
      },
      // 筛选日期可不可点回调函数
      selectableDayPredicate: (dayTime){
        if(dayTime == DateTime(2020, 10, 15) || dayTime == DateTime(2020, 10, 16) || dayTime == DateTime(2020, 10, 17)) {
          return false;
        }
        return true;
      }
    );
  }
CalendarDatePicker year and day.png

7. CupertinoTimerPicker 详解

注意改变 mode 时,不要使用热重载,会报错。

  CupertinoTimerPicker _cupertinoTimePicker(CupertinoTimerPickerMode mode){
    return CupertinoTimerPicker(
      mode: mode, // 展示模式
      initialTimerDuration: Duration(hours: 5, minutes: 10), // 默认选中事时间
      minuteInterval: 10, // 分钟间隔
      secondInterval: 10, // 秒间隔
      alignment: Alignment.center, // 对齐方式
      backgroundColor: Colors.yellow, // 背景颜色
      // 滑动后,每次改变回调函数
      onTimerDurationChanged: (dayTime){
        print("onTimerDurationChanged $dayTime");
      },
    );
  }
CupertinoTimerPicker.png

8. CupertinoDatePicker 详解

CupertinoDatePicker 直接使用在 ListView 中会报错,这里我用一个固定大小的 Container 作为父容器。

  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker"),),
      body: ListView(
        padding: EdgeInsets.all(15),
        children: [
          _showDatePicker(context),
          _showDatePickerForYear(context),
          _showDatePickerForInput(context),
          _showDatePickerForTheme(context),
          _showTimePicker(context),

          Text("CalendarDatePicker day"),
          _calendarDatePicker(DatePickerMode.day),
          Text("CalendarDatePicker year"),
          _calendarDatePicker(DatePickerMode.year),

          Text("_cupertinoTimePicker - hms"),
          _cupertinoTimePicker(CupertinoTimerPickerMode.hms),
          Text("_cupertinoTimePicker - hm"),
          _cupertinoTimePicker(CupertinoTimerPickerMode.hm),
          Text("_cupertinoTimePicker - ms"),
          _cupertinoTimePicker(CupertinoTimerPickerMode.ms),

          Text("CupertinoDatePicker - dateAndTime"),
          _cupertinoDatePicker(CupertinoDatePickerMode.dateAndTime),
          Text("CupertinoDatePicker - date"),
          _cupertinoDatePicker(CupertinoDatePickerMode.date),
        ],
      ),
    );
  }

  Container _cupertinoDatePicker(CupertinoDatePickerMode mode){
    return Container(
      height: 200,
      child: CupertinoDatePicker(
        mode: mode, // 展示模式, 默认为 dateAndTime
        initialDateTime: DateTime(2020, 10, 10), // 默认选中日期
        minimumDate: DateTime(2020, 10, 10), // 最小可选日期
        maximumDate: DateTime(2021, 10, 10), // 最大可选日期

        minimumYear: 2020, // 最小可选年份
        maximumYear: 2021, // 最大可选年份

        minuteInterval: 10, // 分钟间隔

        use24hFormat: true, // 是否采用24小时制
        backgroundColor: Colors.cyan, // 背景色

        onDateTimeChanged: (dayTime){
          print("onDateTimeChanged $dayTime");
        },
      ),
    );
  }
CupertinoDatePicker.png

9. 技术小结

日期选择器样式比较多,但是属性偏少,需要耐心尝试各种不同的选择器。

你可能感兴趣的:(Flutter入门(33):Flutter 组件之时间日期选择器(DatePicker,TimerPicker)详解)