Flutter 时间选择器

2021-11-23 18:30:41 浏览数 (1)

准备工作

需要安装flutter的开发环境:大家可以去看看之前的教程:

1 win系统flutter开发环境安装教程: https://www.jianshu.com/p/152447bc8718

2 mac系统flutter开发环境安装教程:https://www.jianshu.com/p/bad2c35b41e3

需要用到三方库

代码语言:javascript复制
 flutter_picker: 1.1.5
  # 弹框 https://pub.dev/packages/fluttertoast#-installing-tab-
  fluttertoast: ^7.0.4
  # 时间格式转换 https://pub.dev/packages/date_format
  date_format: 1.0.8

请在pubspec.yaml 文件中添加依赖 然后在控制台输入flutter pub get 下载依赖

具体代码实现:

单例

代码语言:javascript复制
   static void showStringPicker<T>(
        BuildContext context, {
          @required List<T> data,
          String title,
          int normalIndex,
          PickerDataAdapter adapter,
          @required _StringClickCallBack clickCallBack,
        }) {
​
        openModalPicker(context,
            adapter: adapter ??  PickerDataAdapter( pickerdata: data, isArray: false),
            clickCallBack:(Picker picker, List<int> selecteds){
              //          print(picker.adapter.text);
            clickCallBack(selecteds[0],data[selecteds[0]]);
           },
        selecteds: [normalIndex??0] ,
            title: title);
        }
 static void openModalPicker(
            BuildContext context, {
              @required PickerAdapter adapter,
              String title,
              List<int> selecteds,
              @required PickerConfirmCallback clickCallBack,
            }) {
          new Picker(
            adapter: adapter,
            title: new Text(title ?? "请选择",style:TextStyle(color: _kTitleColor,fontSize: _kTextFontSize)),
            selecteds: selecteds,
            cancelText: '取消',
            confirmText: '确定',
            cancelTextStyle: TextStyle(color: _kBtnColor,fontSize: _kTextFontSize),
            confirmTextStyle: TextStyle(color: _kBtnColor,fontSize: _kTextFontSize),
            textAlign: TextAlign.right,
            itemExtent: _kItemHeight,
            height: _kPickerHeight,
            selectedTextStyle: TextStyle(color: Colors.black),
            onConfirm:clickCallBack
          ).showModal(context);
        }

我们定义了一个 静态方法 showStringPicker () 需要传入上下文 context 显示列表数据 @required List<T> data, 还有 String title, 以及PickerDataAdapter 适配器 和回调 @required _StringClickCallBack clickCallBack,

具体外部调用

单列
代码语言:javascript复制
JhPickerTool.showStringPicker(context,
                  data: aa,
                  normalIndex: 2,
      //          title: "请选择2",
                  clickCallBack: (int index,var str){
                   print(index);
                   print(str);
                   showText(str);
                 }
            );
多列
代码语言:javascript复制
 JhPickerTool.showArrayPicker(context,
                    data: bb,
                    title: "请选择2",
                    normalIndex: [0,1,0],
                    clickCallBack:(var index, var strData){
                    print(index);
                    print(strData);
                    showText(strData);
                    }
                );

具体实现:

代码语言:javascript复制
static void showDatePicker(
          BuildContext context, {
          DateType dateType,
          String title,
          DateTime maxValue,
          DateTime minValue,
          DateTime value,
          DateTimePickerAdapter adapter,
          @required _DateClickCallBack clickCallback,
          }) {
​
        int timeType;
        if(dateType == DateType.YM){
          timeType =  PickerDateTimeType.kYM;
        }else if(dateType == DateType.YMD_HM){
          timeType =  PickerDateTimeType.kYMDHM;
        }else if(dateType == DateType.YMD_AP_HM){
          timeType =  PickerDateTimeType.kYMD_AP_HM;
        }else{
          timeType =  PickerDateTimeType.kYMD;
        }
        openModalPicker(context,
        adapter: adapter ??
        DateTimePickerAdapter(
        type: timeType,
        isNumberMonth: true,
        yearSuffix: "年",
        monthSuffix: "月",
        daySuffix: "日",
        strAMPM: const["上午", "下午"],
        maxValue: maxValue ,
        minValue: minValue,
        value: value ?? DateTime.now(),
        ),
        title: title,
        clickCallBack:(Picker picker, List<int> selecteds){
​
          var time = (picker.adapter as DateTimePickerAdapter).value;
          var timeStr;
          if(dateType == DateType.YM){
            timeStr =time.year.toString() "年" time.month.toString() "月";
          }else if(dateType == DateType.YMD_HM){
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" time.hour.toString() "时" time.minute.toString() "分";
          }else if(dateType == DateType.YMD_AP_HM){
          var str = formatDate(time, [am])=="AM" ? "上午":"下午";
          timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" str time.hour.toString() "时" time.minute.toString() "分";
          }else{
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日";
          }
//          print(formatDate(DateTime(1989, 02, 21), [yyyy, '-', mm, '-', dd]));
             clickCallback(timeStr,picker.adapter.text);
          }
          );
   }

这边获取时间选择器 通过调用showDatePicker 方法

代码语言:javascript复制
    static void showDatePicker(
          BuildContext context, {
          DateType dateType,
          String title,
          DateTime maxValue,
          DateTime minValue,
          DateTime value,
          DateTimePickerAdapter adapter,
          @required _DateClickCallBack clickCallback,
          })

我们这边需要传入 对应上下文 context 还有 时间选择器类型 DateType 对应我们上图的四种样式 YM , YMD_HM ,YMD_AP_HM kYMD 这四种 还需传入 最大时间和最小时间 DateTime maxValue, DateTime minValue, 这个非毕传 看具体情况使用 ,以及我们的适配器 我们根据外部传入的时间类型 我们把需要用到dataType 重新赋值

代码语言:javascript复制
int timeType;
        if(dateType == DateType.YM){
          timeType =  PickerDateTimeType.kYM;
        }else if(dateType == DateType.YMD_HM){
          timeType =  PickerDateTimeType.kYMDHM;
        }else if(dateType == DateType.YMD_AP_HM){
          timeType =  PickerDateTimeType.kYMD_AP_HM;
        }else{
          timeType =  PickerDateTimeType.kYMD;
        }

然后我们在showDatePicker 方法体里面调用 openModalPicker 我们封装好底部弹窗选择器的方法

代码语言:javascript复制
    openModalPicker(context,
        adapter: adapter ??
        DateTimePickerAdapter(
        type: timeType,
        isNumberMonth: true,
        yearSuffix: "年",
        monthSuffix: "月",
        daySuffix: "日",
        strAMPM: const["上午", "下午"],
        maxValue: maxValue ,
        minValue: minValue,
        value: value ?? DateTime.now(),
        ),
        title: title,
        clickCallBack:(Picker picker, List<int> selecteds){
​
          var time = (picker.adapter as DateTimePickerAdapter).value;
          var timeStr;
          if(dateType == DateType.YM){
            timeStr =time.year.toString() "年" time.month.toString() "月";
          }else if(dateType == DateType.YMD_HM){
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" time.hour.toString() "时" time.minute.toString() "分";
          }else if(dateType == DateType.YMD_AP_HM){
          var str = formatDate(time, [am])=="AM" ? "上午":"下午";
          timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" str time.hour.toString() "时" time.minute.toString() "分";
          }else{
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日";
          }
//          print(formatDate(DateTime(1989, 02, 21), [yyyy, '-', mm, '-', dd]));
             clickCallback(timeStr,picker.adapter.text);
          }
          );

我们在 DateTimePickerAdapter 适配器总传入我们从外部传入的参数以及获取到当前时间 DateTime.now(), 我们在 callback 回调方法中 通过picker.adapter 获取到适配器里面的属性value 拿到当前选择的时间

代码语言:javascript复制
      var time = (picker.adapter as DateTimePickerAdapter).value;
具体转化
代码语言:javascript复制
    clickCallBack:(Picker picker, List<int> selecteds){
​
          var time = (picker.adapter as DateTimePickerAdapter).value;
          var timeStr;
          if(dateType == DateType.YM){
            timeStr =time.year.toString() "年" time.month.toString() "月";
          }else if(dateType == DateType.YMD_HM){
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" time.hour.toString() "时" time.minute.toString() "分";
          }else if(dateType == DateType.YMD_AP_HM){
          var str = formatDate(time, [am])=="AM" ? "上午":"下午";
          timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日" str time.hour.toString() "时" time.minute.toString() "分";
          }else{
            timeStr =time.year.toString() "年" time.month.toString() "月" time.day.toString() "日";
          }
//          print(formatDate(DateTime(1989, 02, 21), [yyyy, '-', mm, '-', dd]));
             clickCallback(timeStr,picker.adapter.text);
          }

然后进行格式化 年 月 日 这样 返回给调用页面

具体时间选择器调用

代码语言:javascript复制
 if(str == "jhPickerTool-时间选择YM"){
​
            JhPickerTool.showDatePicker(
                context,
                dateType: DateType.YM,
                clickCallback: (var str,var time){
                  print(str);
                  print(time);
                  showText(str);
                }
            );
          }
          if(str == "jhPickerTool-时间选择YMD_HM"){
​
            JhPickerTool.showDatePicker(
                context,
                dateType: DateType.YMD_HM,
                clickCallback: (var str,var time){
                  print(str);
                  print(time);
                  showText(str);
                }
            );
​
          }
          if(str == "jhPickerTool-时间选择YMD_AP_HM"){
​
            JhPickerTool.showDatePicker(
                context,
                dateType: DateType.YMD_AP_HM,
                clickCallback: (var str,var time){
                  print(str);
                  print(time);
                  showText(str);
                }
            );
          }
          }

到此我们时间选择器和底部选择器单列多列就算讲完了

最后总结:

flutter里面提供比较好用的 flutter_picker: 1.1.5 date_format: 1.0.8 底部选择器和 时间转换的库 供我们调用 所以底部弹窗的实现 这里也要感谢作者的共享 能让我们开发变得简单 有兴趣的同学可以私研究用其他的方式可以实现也行我这里就不展开讲了 , 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。

0 人点赞