flutter picker 选择器

 

先上效果图

 

   

单列选择器

// 定义一个单列的数据集合
var aa = ["11","22","33","44"];

// 调用PickerTool来显示一个单列选择器
PickerTool.showStringPicker(context,
  data: aa,  // 数据源
  // normalIndex: 2, // 默认选中的项的索引
  // title: "请选择2", // 选择器的标题
  clickCallBack: (int index,var str){
    print(index); // 打印选中的项的索引
    print(str);   // 打印选中的数据值
  }
);

多列选择器

// 定义一个多列的数据集合
var bb = [["11","22"],["33","44"],["55","66"]];

// 调用PickerTool来显示一个多列选择器
PickerTool.showArrayPicker(context,
  data: bb,  // 数据源
  // title: "请选择2", // 选择器的标题
  // normalIndex: [0,1,0], // 默认选中的项的索引
  clickCallBack:(var index, var strData){
    print(index); // 打印选中的项的索引
    print(strData); // 打印选中的数据值
  }
);

日期选择器

// 调用PickerTool来显示一个日期选择器
PickerTool.showDatePicker(context,
  // dateType: DateType.YMD, // 选择的日期类型,例如年月日
  // dateType: DateType.YM, // 选择的日期类型,例如年月
  // dateType: DateType.YMD_HM, // 选择的日期类型,例如年月日时分
  // dateType: DateType.YMD_AP_HM, // 选择的日期类型,例如年月日上午/下午时分
  // title: "请选择2", // 选择器的标题
  // minValue: DateTime(2020,10,10), // 可选的最小日期
  // maxValue: DateTime(2023,10,10), // 可选的最大日期
  // value: DateTime(2020,10,10), // 默认选中的日期
  clickCallback: (var str,var time){
    print(str); // 打印选中的日期字符串
    print(time); // 打印选中的日期对象
  }
);

代码实现

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

// 下面是一些用于配置Picker的常量。
final double kPickerHeight = Screen.width(216.0); // Picker控件的总体高度
const double kItemHeight = 40.0;                   // 每一项的高度
const Color kBtnColor = Color(0xFF323232);         // 按钮的颜色
const Color kTitleColor = Color(0xFF787878);       // 标题文本的颜色
const double kTextFontSize = 17.0;                 // 文本的字体大小

// 下面定义了几种点击事件的回调类型,用于处理Picker选择后的事件。
typedef StringClickCallback = void Function(int selectIndex,Object selectStr);     // 单列选择器的回调
typedef ArrayClickCallback = void Function( List<int> selecteds,List<dynamic> strData);  // 多列选择器的回调
typedef DateClickCallback = void Function(dynamic selectDateStr,dynamic selectDate);   // 日期选择器的回调

// 日期类型枚举,用于定义日期选择器的展示形式。
enum DateType {
  YMD,        // 只展示年月日
  YM,         // 只展示年月
  YMD_HM,     // 展示年月日时分
  YMD_AP_HM,  // 展示年月日以及上午/下午时分
}

// PickerTool类是一个工具类,用于快速创建不同类型的Picker。
class PickerTool {

  // 单列选择器。
  static void showStringPicker<T>(
      BuildContext context, {
        @required List<T> data,  // 数据源,这是一个必须传入的参数。
        String title,            // Picker的标题,如果不传入,则默认为空。
        int normalIndex,         // 默认选中项的索引,即Picker初始化时默认显示的项。
        PickerDataAdapter adapter, // Picker的数据适配器,如果不传入,则默认为非数组模式。
        @required StringClickCallback clickCallBack, // 当用户选择完毕点击确定后的回调函数。
      }) {
    openModalPicker(context,
        adapter: adapter ??  PickerDataAdapter(pickerdata: data, isArray: false),
        clickCallBack:(Picker picker, List<int> selecteds){
          clickCallBack(selecteds[0],data[selecteds[0]]);
        },
        selecteds: [normalIndex??0],  // 默认选中项的索引列表。
        title: title);
  }

  // 多列选择器。
  static void showArrayPicker<T>(
      BuildContext context, {
        @required List<T> data,  // 数据源
        String title,            // 选择器的标题
        List<int> normalIndex,   // 默认选中的项的索引列表
        PickerDataAdapter adapter, // Picker的数据适配器,如果不传入,则默认为数组模式。
        @required ArrayClickCallback clickCallBack, // 选择完毕的回调函数
      }) {
    openModalPicker(context,
        adapter: adapter ??  PickerDataAdapter( pickerdata: data, isArray: true),
        clickCallBack:(Picker picker, List<int> selecteds){
          clickCallBack(selecteds, picker.getSelectedValues());
        },
        selecteds: normalIndex,
        title: title);
  }

  // 打开模态的Picker。
  static void openModalPicker(
      BuildContext context, {
        @required PickerAdapter adapter,             // 适配器,用于提供Picker的数据。
        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);
  }

  // 日期选择器。
  static void showDatePicker(
      BuildContext context, {
        DateType dateType,                       // 日期类型
        String title,                            // 选择器的标题
        DateTime maxValue,                       // 可选择的最大日期
        DateTime minValue,                       // 可选择的最小日期
        DateTime value,                          // 默认显示的日期
        DateTimePickerAdapter adapter,           // 日期选择器的适配器
        @required DateClickCallback clickCallback, // 选择日期后的回调函数
      }) {

    // 根据传入的日期类型,设置对应的PickerDateTimeType。
    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() + "日";
          }
          clickCallback(timeStr, picker.adapter.text);
        }
    );
  }
}

posted on 2020-03-16 17:58  完美前端  阅读(5145)  评论(0)    收藏  举报

导航