Flutter 時間選擇器實現教程


前言

各位同學大家好 有段時間沒有給大家更新文章了,具體多久我也記不清楚了 ,最近寫了一個flutter時間選擇的demo 就想着分享給大家 那么廢話不多說我們正式開始

准備工作

需要安裝flutter的開發環境:大家可以去看看之前的教程:
1 win系統flutter開發環境安裝教程: https://www.jianshu.com/p/152447bc8718
2 mac系統flutter開發環境安裝教程:https://www.jianshu.com/p/bad2c35b41e3

效果圖:

image.png
image.png
image.png
image.png
image.png
image.png

需要用到三方庫

 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 下載依賴
image.png
image.png

具體代碼實現:

單例

   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 data, 還有 String title, 以及PickerDataAdapter 適配器 和回調 @required _StringClickCallBack clickCallBack,

具體外部調用

單列

JhPickerTool.showStringPicker(context,
                  data: aa,
                  normalIndex: 2,
      //          title: "請選擇2",
                  clickCallBack: (int index,var str){
                   print(index);
                   print(str);
                   showText(str);
                 }
            );
多列
 JhPickerTool.showArrayPicker(context,
                    data: bb,
                    title: "請選擇2",
                    normalIndex: [0,1,0],
                    clickCallBack:(var index, var strData){
                    print(index);
                    print(strData);
                    showText(strData);
                    }
                );

時間選擇器:

image.png
image.png
image.png

具體實現:

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 方法

    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 重新賦值

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 我們封裝好底部彈窗選擇器的方法

    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 拿到當前選擇的時間

      var time = (picker.adapter as DateTimePickerAdapter).value;

具體轉化

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

然后進行格式化 年 月 日 這樣 返回給調用頁面

具體時間選擇器調用

 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 底部選擇器和 時間轉換的庫 供我們調用 所以底部彈窗的實現 這里也要感謝作者的共享 能讓我們開發變得簡單 有興趣的同學可以私研究用其他的方式可以實現也行我這里就不展開講了 , 最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這里謝過啦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM