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

如上图,此类需求,需要特殊处理,由于本人很懒就自己写了一套: 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 onChanged; //传值
 final int type; //
 const CarKeyboard({
Key key,
this.onChanged,
this.type,
}) : super(key: key);
@override
_CarKeyboardState createState() => _CarKeyboardState();
}

class _CarKeyboardState extends State {
  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 postNameMap = Map();

 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 车牌号/身份证等特殊输入框,以及通知传值)