美文网首页
Flutter 车牌号/身份证等特殊输入框,以及通知传值

Flutter 车牌号/身份证等特殊输入框,以及通知传值

作者: 技术混子 | 来源:发表于2020-10-21 20:17 被阅读0次

    如上图,此类需求,需要特殊处理,由于本人很懒就自己写了一套: Container套text来实现此需求。

    Top 1.
    用 GridView.builder 来实现 那几个框框

    GridView.builder(
                                                      shrinkWrap: true,
                                                      physics:
                                                          new NeverScrollableScrollPhysics(),
                                                      //禁止滑动
                                                      itemCount: 8,
                                                      //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
                                                      gridDelegate:
                                                          SliverGridDelegateWithFixedCrossAxisCount(
                                                              //横轴元素个数
                                                              crossAxisCount: 8,
                                                              //纵轴间距
                                                              mainAxisSpacing:
                                                                  0.0,
                                                              //横轴间距
                                                              crossAxisSpacing:
                                                                  5.0,
                                                              //子组件宽高长度比例
                                                              childAspectRatio:
                                                                  15 / 20),
                                                      itemBuilder:
                                                          (BuildContext context,
                                                              int item) {
                                                        return Container(
                                                          width: 15,
                                                          height: 20,
                                                          decoration: BoxDecoration(
                                                              borderRadius:
                                                                  BorderRadius
                                                                      .circular(
                                                                          5),
                                                              border: Border.all(
                                                                  color: item ==
                                                                          vecList.length -
                                                                              1
                                                                      ? Color.fromRGBO(
                                                                          39,
                                                                          153,
                                                                          93,
                                                                          1)
                                                                      : Color
                                                                          .fromRGBO(
                                                                              8,
                                                                              8,
                                                                              8,
                                                                              1),
                                                                  width: 1)),
                                                          child: Align(
                                                            alignment: Alignment
                                                                .center,
                                                            child: Text(
                                                              //用于解决 车牌号未输入完其余空展示
                                                              vecList.length ==
                                                                      8
                                                                  ? vecList[
                                                                      item]
                                                                  : item <
                                                                          vecList
                                                                              .length
                                                                      ? vecList[
                                                                          item]
                                                                      : '',
                                                              style: TextStyle(
                                                                  color: Color
                                                                      .fromRGBO(
                                                                          8,
                                                                          8,
                                                                          8,
                                                                          1),
                                                                  fontSize: 14),
                                                            ),
                                                          ),
                                                        );
                                                      }),
    

    Top 2.
    用 InkWell来做点击事件

     InkWell( onTap: () {})
    

    Top 3.
    用showModalBottomSheet 展示仿键盘弹出样式
    点击事件代码如下,利用list与string 的转换来展示信息

    InkWell(  onTap: () {
                                                    showModalBottomSheet(
                                                      barrierColor:
                                                          Color.fromRGBO(
                                                              255, 255, 255, 0),
                                                      isScrollControlled: true,
                                                      isDismissible: true,
                                                      enableDrag: false,
                                                      context: context,
                                                      builder: (BuildContext
                                                          context) {
                                                        return CarKeyboard(
                                                          type: ocrBool ? 1 : 0,
                                                          onChanged: (value) {
                                                            setState(() {
                                                              if (value ==
                                                                  'del') {
                                                                if (vecList
                                                                        .length >
                                                                    0) {
                                                                  vecList
                                                                      .removeLast();
                                                                }
                                                                if (vecList
                                                                        .length ==
                                                                    0) {
                                                                  ocrBool =
                                                                      false;
                                                                  //发送通知
                                                                  NotificationCenter
                                                                      .instance
                                                                      .postNotification(
                                                                          'change',
                                                                          0);
                                                                }
                                                              } else {
                                                                ocrBool = true;
                                                                //车牌号展示 逻辑
                                                                if (vecList
                                                                        .length <
                                                                    8) {
                                                                  vecList.add(
                                                                      value);
                                                                }
                                                              }
    
                                                              //数组list转 string
                                                              String result;
                                                              vecList.forEach(
                                                                  (string) => {
                                                                        if (result ==
                                                                            null)
                                                                          result =
                                                                              string
                                                                        else
                                                                          result =
                                                                              '$result$string'
                                                                      });
                                                              dataMap['vehicleLicence'] =
                                                                  result;
    
                                                            
                                                              print(
                                                                  '回调车牌:$result');
                                                            });
                                                          },
                                                        );
                                                      },
                                                    );
                                                  },
    

    Top 4.
    CarKeyboard 封装代码

    const PROVINCES = [
      '京',  '沪', '津', '渝', '冀','晋','蒙', '辽','吉','黑','苏','浙', '皖','闽','赣','鲁','豫',      '鄂', '湘','粤','桂',  '琼',  '川',  '贵', '云', '藏','陕', '甘','青','宁', '新'
    ];
    const ALPHABETS = [
     'A',  'B', 'C', 'D', 'E', 'F', 'G','H', 'I',  'J','K',  'L', 'M','N','O', 'P', 'Q', 'R', 'S', 'T', 'U',
      'V','W','X', 'Y', 'Z', '0', '1','2', '3', '4',  '5','6','7','8','9',
      '学', '警','挂',
    ];
    
    class CarKeyboard extends StatefulWidget {
     final ValueChanged<String> onChanged; //传值
     final int type; //
     const CarKeyboard({
    Key key,
    this.onChanged,
    this.type,
    }) : super(key: key);
    @override
    _CarKeyboardState createState() => _CarKeyboardState();
    }
    
    class _CarKeyboardState extends State<CarKeyboard> {
      bool showBool = true;
      @override
     void initState() {
      // TODO: implement initState
    super.initState();
    widget.type == 1 ? showBool = false : showBool = true;
     }
    
      @override
      Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Container(
            color: Color.fromRGBO(192, 198, 199, 0.7),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                SizedBox(
                  height: 10,
                ),
                Row(
                  children: [
                    SizedBox(
                      width: 10,
                    ),
                    InkWell(
                      onTap: () {
                        Navigator.pop(context);
                      },
                      child: Container(
                          width: 50,
                          height: 40,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(5),
                              color: Color.fromRGBO(164, 170, 174, 1)),
                          child: Align(
                            alignment: Alignment.center,
                            child: Text(
                              '取消',
                              style: TextStyle(
                                  color: Colors.black,
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold),
                            ),
                          )),
                    ),
                    Expanded(child: SizedBox()),
                    Text(
                      '选择车牌号',
                      style: TextStyle(
                          color: Colors.black,
                          fontSize: 14,
                          fontWeight: FontWeight.bold),
                    ),
                    Expanded(child: SizedBox()),
                    InkWell(
                      onTap: () {
                        widget.onChanged('del');
                        //添加监听者
                        NotificationCenter.instance.addObserver('change',
                            (object) {
                          setState(() {
                            if (object == 0) showBool = true;
                            if (object == 1) showBool = false;
                            //移除监听
                            NotificationCenter.instance
                                .removeNotification('change');
                          });
                        });
                      },
                      child: Container(
                          width: 50,
                          height: 40,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(5),
                              color: Color.fromRGBO(164, 170, 174, 1)),
                          child: Align(
                            alignment: Alignment.center,
                            child: Text(
                              'X',
                              style: TextStyle(
                                  color: Colors.black,
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold),
                            ),
                          )),
                    ),
                    SizedBox(
                      width: 10,
                    ),
                  ],
                ),
                SizedBox(
                  height: 10,
                ),
                Row(children: [
                  SizedBox(
                    width: 10,
                  ),
                  Expanded(
                      child: GridView.builder(
                          shrinkWrap: true,
                          // physics:  NeverScrollableScrollPhysics(),
                          //禁止滑动
                          itemCount:
                              showBool ? PROVINCES.length : ALPHABETS.length,
                          //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
                          gridDelegate:
                              SliverGridDelegateWithFixedCrossAxisCount(
                                  //横轴元素个数
                                  crossAxisCount: 7,
                                  //纵轴间距
                                  mainAxisSpacing: 10.0,
                                  //横轴间距
                                  crossAxisSpacing: 10.0,
                                  //子组件宽高长度比例
                                  childAspectRatio: 30 / 30),
                          itemBuilder: (BuildContext context, int item) {
                            return InkWell(
                              onTap: () {
                                setState(() {
                                  widget.onChanged(showBool
                                      ? PROVINCES[item]
                                      : ALPHABETS[item]);
    
                                  if (showBool) {
                                    showBool = false;
                                  }
                                });
                              },
                              child: Container(
                                width: 30,
                                height: 30,
                                decoration: BoxDecoration(
                                    borderRadius: BorderRadius.circular(5),
                                    color: Colors.white),
                                child: Align(
                                  alignment: Alignment.center,
                                  child: Text(
                                    showBool
                                        ? PROVINCES[item]
                                        : ALPHABETS[item],
                                    style: TextStyle(
                                        color: Color.fromRGBO(8, 8, 8, 1),
                                        fontSize: 14),
                                  ),
                                ),
                              ),
                            );
                          })),
                  SizedBox(
                    width: 10,
                  ),
                ]),
                SizedBox(
                  height: 10,
                ),
              ],
            )));
     }
    }
    

    ocrBool 用于点击时 甄别展示仿键盘样式
    NotificationCenter 用于全部删除后的 仿键盘样式展示

       //发送通知
      NotificationCenter.instance .postNotification( 'change', 0);
    

    通知的实现方式

    封装一个公共类

    //借鉴 前辈的 代码
    typedef GetObject = Function(dynamic object);
    
    class NotificationCenter {
     // 工厂模式
     factory NotificationCenter() => _getInstance();
    
     static NotificationCenter get instance => _getInstance();
     static NotificationCenter _instance;
    
     NotificationCenter._internal() {
      // 初始化
    }
    
      static NotificationCenter _getInstance() {
    if (_instance == null) {
      _instance = new NotificationCenter._internal();
    }
    return _instance;
     }
    
     //创建Map来记录名称
     Map<String, dynamic> postNameMap = Map<String, dynamic>();
    
     GetObject getObject;
    
     //添加监听者方法
    addObserver(String postName, object(dynamic object)) {
      postNameMap[postName] = null;
      getObject = object;
    }
    
     //发送通知传值
     postNotification(String postName, dynamic object) {
      //检索Map是否含有postName
       if (postNameMap.containsKey(postName)) {
        postNameMap[postName] = object;
        getObject(postNameMap[postName]);
      }
    }
    
     //移除通知
     removeNotification(String postName) {
       if (postNameMap.containsKey(postName)) {
        postNameMap.remove(postName);
      }
     }
    }
    

    创建通知

    //添加监听者
    NotificationCenter.instance.addObserver('change',(object) {
            setState(() { });
     });
    

    发送通知

    //发送通知
         NotificationCenter .instance .postNotification(  'change', 0);
    

    移除通知

      //移除监听
    
     NotificationCenter.instance .removeNotification('change');
    

    表达不是很好希望对各位有所帮助!!!

    相关文章

      网友评论

          本文标题:Flutter 车牌号/身份证等特殊输入框,以及通知传值

          本文链接:https://www.haomeiwen.com/subject/zsgemktx.html