我这边没有把 输入框 和 键盘封装在一起,只封装了键盘 这几本能满足日常用途了  日常使用到独立的数字键盘的场景不多 

用例

OverlayEntry overlayEntry;
TextEditingController controller = TextEditingController();

TextField(
  controller: controller,
  onTap: (){
    // 使用键盘
    numberKeypan(
      initialization: (v){
        /// 初始化
        overlayEntry = v;
        /// 唤起键盘
        openKeypan(context: context);
      },
      onDel: (){
        delCursor(textEditingController: controller);
      },
      onTap: (v){
        /// 更新输入框的值
        controller.text += v;
        /// 保持光标
        lastCursor(textEditingController: controller);
      },
    );
  },
  showCursor: true, //显示光标
  readOnly: true, // 禁用唤起系统键盘 
),

注:未点击回车键时 离开当前页面时 需要调用 disKeypan( )  销毁键盘 否则会一直浮动在最上层,除了回车事件带销毁 其他场景情况 需手动销毁浮动的键盘

封装


import 'package:flutter/material.dart';

/// <summary>
/// todo: 数字键盘
/// author:zwb
/// dateTime:2021/7/19 10:25
/// filePath:lib/app/widgets/number_keypan.dart
/// desc:  
/// <summary> 
OverlayEntry overlayEntry;
numberKeypan({@required Function(OverlayEntry) initialization,@required Function(String) onTap,Function onCommit,Function onDel,}){
  overlayEntry = OverlayEntry(builder: (context) {
    List<String> list = ['1','2','3','4','5','6','7','8','9','','0','.'];
    return new Positioned(
        bottom: 0,
        child: new Material(
          child: new Container(
            width: MediaQuery.of(context).size.width,
            alignment: Alignment.center,
            color: Colors.grey[200],
            child: Row(
              children: [
                Expanded(
                  child: Wrap(
                    alignment: WrapAlignment.spaceBetween,
                    children: List.generate(list.length, (index) {
                      return Material(
                        color: Colors.white,
                        child: Ink(
                          child: InkWell(
                            child: Container(
                              decoration: BoxDecoration(
                                border: Border.all(color: Colors.grey[200],width: 0.25),
                              ),
                              alignment: Alignment.center,
                              height: 50,
                              width: (MediaQuery.of(context).size.width - 60) / 3,
                              child: Text("${list[index]}",style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold),),
                            ),
                            onTap: (){
                              if(list[index] != ""){
                                onTap(list[index]);
                              }
                            },
                          ),
                          color: Colors.white,
                        ),
                      );
                    }),
                  ),
                ),
                Column(
                  children: [
                    SizedBox(
                      width: 60,
                      height: 50 * 1.5,
                      child: MaterialButton(
                        onPressed:  onDel ?? (){},
                        child: Text("删除",style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold)),
                        color: Colors.grey[100],
                        elevation: 0,
                        padding: EdgeInsets.all(0),),
                    ),
                    SizedBox(
                      width: 60,
                      height: 50 * 2.5,
                      child: MaterialButton(
                        onPressed: (){
                          disKeypan();
                          if(onCommit != null ) onCommit();
                        },
                        child: Text("回车",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),),
                        color: Colors.blue,
                        elevation: 0,
                        padding: EdgeInsets.all(0),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ));
  });
  initialization(overlayEntry);
}

/// <summary>
/// todo: 保持光标在最后
/// author: zwb
/// date: 2021/7/19 11:43
/// param: 参数
/// return: void
/// <summary>
///
lastCursor({@required TextEditingController textEditingController}){
  /// 保持光标在最后
  final length = textEditingController.text.length;
  textEditingController.selection = TextSelection(baseOffset:length , extentOffset:length);
}

/// <summary>
/// todo: 自定义键盘的删除事件
/// author: zwb
/// date: 2021/7/19 11:45
/// param: 参数
/// return: void
/// <summary>
///
delCursor({@required TextEditingController textEditingController}){
  if(textEditingController != null && textEditingController.value.text != "") textEditingController.text = textEditingController.text.substring(0,textEditingController.text.length - 1);
}

/// <summary>
/// todo: 打开键盘
/// author: zwb
/// date: 2021/7/19 12:04
/// param: 参数
/// return: void
/// <summary>
///
openKeypan({BuildContext context}){
  Overlay.of(context).insert(overlayEntry);
}

/// <summary>
/// todo: 销毁键盘
/// author: zwb
/// date: 2021/7/19 12:03
/// param: 参数
/// return: void
/// <summary>
///
disKeypan(){
  overlayEntry.remove();
}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐