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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350