欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

flutter实现扫码枪获取数据源禁止系统键盘弹窗示例详解,

来源: javaer 分享于  点击 32661 次 点评:168

flutter实现扫码枪获取数据源禁止系统键盘弹窗示例详解,


目录
  • 序言
    • 使用方式:
  • 两种场景能力支持
    • 技术点分析
      • 1. 如何获取扫码枪输入内容
      • 2. 键盘弹出问题
      • 3. 扩展,如何自定义监听数据源输入

    序言

    小编在项目中有遇到使用 flutter 实现扫码枪接入的需求。为方便使用,小编把能力封装成 package 并发布。好记性不如烂笔头,下面是该插件的使用方式,以及途中遇到的坑和处理想法。

    使用方式:

    • 在pubspec.yaml文件中进行引用:
    dependencies:
      scan_gun: ^1.0.0
    
    • 提供 ScanMonitorWidget 作为父节点,嵌套使用:
      ScanMonitorWidget({
        Key? key,
        required ChildBuilder childBuilder,
        FocusNode? scanNode,
        FocusNode? textFiledNode,
        required void Function(String) onSubmit,
      })
    

    参数说明:

    • childBuilder :

    typedef ChildBuilder = Widget Function(BuildContext context),使用者自己UI作为子节点

    • scanNode:

    非必传,如果传,可通过 scanNode 监听获取当前扫码可用状态,hasFocus 时为可用也可通过 scanNode requestFocus 方法,强制扫码获取焦点,保证扫码能力

    • textFiledNode:

    提供外部存在输入框键盘输入与扫码输入同时存在的场景。内部做了焦点切换能力,保证输入框焦点取消后,能马上切换成扫码枪的焦点

    • onSubmit:

    接收扫码枪返回的结果

    两种场景能力支持

    • 无输入框交互,获取扫码结果:
    @override
      Widget build(BuildContext context) {
        return ScanMonitorWidget(
          childBuilder: (context) {
            return body();
          },
          onSubmit: (String result) {
            print(result); //接收到扫码结果
          },
        );
      }
    
    • 带输入框交互,获取扫码结果:
    FocusNode textFiledNode = FocusNode();
    TextEditingController controller = TextEditingController();
     Widget body() {
      return TextField(
         focusNode: textFiledNode,
         controller: controller,
       );
     }
    @override
      Widget build(BuildContext context) {
        return ScanMonitorWidget(
          textFiledNode: textFiledNode,
          childBuilder: (context) {
            return body();
          },
          onSubmit: (String result) {
            print(result); //接收到扫码结果
          },
        );
      }
    

    github 源码已上传 :传送门

    目前该方案为非通用方案,依赖 flutter 版本进行定制,小编使用的是 Flutter 2.8.1 ,后续更新通用方案。

    技术点分析

    1. 如何获取扫码枪输入内容

    使用过 flutter 编写输入框的同学都用过 TextField ,通过源码我们可以看到 TextField 的功能实现者是它的子节点:EditableText

    扫码枪本质上是一个外接的输入设备。将 EditableText 封装,控制隐藏。可通过获取 EditableText 的内容来获取扫码枪的输入内容。

    控制隐藏可使用 Offstage 标签:

        return Stack(
          children: [
            //让输入框保持隐藏
            Offstage(child: edtWidget, offstage: true),
            child,
          ],
        );
    

    2. 键盘弹出问题

    使用 EditableText 的过程中遇到了系统键盘弹出的问题。我们通过 Edit 的焦点来获取扫码枪的输入。但 EditableText 一旦获取了焦点,内部会调用原生层唤起键盘。这个问题怎么处理呢?

    首先,我们来看看源码中 EditableText 是如何唤起键盘的。 省略非关键代码,直接定位到 EditableTextState

    当焦点变化时,调用了 _openOrCloseInputConnectionIfNeeded()

    _openInputConnection() 方法中通过 TextInput 唤起系统键盘

    既然了解到了EditableText唤起键盘的逻辑,通过自定义 EditableText,将 TextInput.show 步骤过滤掉,只保留单纯的通过焦点获取输入源内容的能力。

    3. 扩展,如何自定义监听数据源输入

    TextInput 源码中,可以发现键盘等输入的数据通过 MessageChannel 的方式进行数据流转:

    由于篇幅原因,这里小编只做抛砖引玉。下面列出核心代码部分:

      void listenKeyboard() {
        SystemChannels.textInput.setMethodCallHandler((call) => _handleTextInputInvocation(call));
      }
    
    String scanData = '';
    void _update(){
        setState(() {});
      }
    Future<dynamic> _handleTextInputInvocation(MethodCall methodCall) async {
        final String method = methodCall.method;
        final List<dynamic> args = methodCall.arguments as List<dynamic>;
        switch (method) {
          case 'TextInputClient.updateEditingState': //每次的内容变化会进来这里
            final data = TextEditingValue.fromJSON(args[1] as Map<String, dynamic>);
            final text = data.text;
            scanData += text;
            dev.log('rex: -updateEditingState - $text');
            break;
          case 'TextInputClient.performAction':
            final action = args[1] as String;
            dev.log('rex: -performAction - $action');
            if(action == 'TextInputAction.none'){ //点击确定
              _update();
            }
            break;
          default:
            throw MissingPluginException();
        }
      }

    以上就是flutter实现扫码枪获取数据源禁止系统键盘弹窗示例详解的详细内容,更多关于flutter扫码枪获取数据源的资料请关注3672js教程其它相关文章!

    您可能感兴趣的文章:
    • Flutter网络请求Dio库的使用及封装详解
    • Flutter Http网络请求实现详解
    • Flutter网络请求库DIO的基本使用
    • flutter优雅实现扫码枪获取数据源示例详解
    • flutter中的网络请求数据获取详解
    相关栏目:

    用户点评