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

 更新时间:2023年01月11日 09:27:46   作者:李小轰_Rex  
这篇文章主要为大家介绍了flutter实现扫码枪获取数据源禁止系统键盘弹窗示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

序言

小编在项目中有遇到使用 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扫码枪获取数据源的资料请关注脚本之家其它相关文章!

相关文章

  • Android图表库HelloChart绘制多折线图

    Android图表库HelloChart绘制多折线图

    这篇文章主要为大家详细介绍了Android图表库HelloChart绘制多折线图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Android Jetpack中Room的使用

    Android Jetpack中Room的使用

    这篇文章主要介绍了Android Jetpack中Room的使用,大家都知道Room主要分三个部分 database、dao和实体类entity,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-10-10
  • android 把float转换成Int的实例讲解

    android 把float转换成Int的实例讲解

    今天小编就为大家分享一篇android 把float转换成Int的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Android实现仿360桌面悬浮清理内存

    Android实现仿360桌面悬浮清理内存

    今天给大家带来一个仿360手机卫士悬浮窗清理内存的效果的教程,非常的简单实用,需要的小伙伴可以参考下
    2015-12-12
  • Android使用ViewPager实现顶部tabbar切换界面

    Android使用ViewPager实现顶部tabbar切换界面

    这篇文章主要为大家详细介绍了使用ViewPager实现顶部tabbar切换界面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Android进度条控件progressbar使用方法详解

    Android进度条控件progressbar使用方法详解

    这篇文章主要为大家详细介绍了Android进度条控件progressbar的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Flutter检查连接网络connectivity_plus实现步骤

    Flutter检查连接网络connectivity_plus实现步骤

    这篇文章主要为大家介绍了Flutter检查连接网络connectivity_plus实现步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Android实战教程第一篇之最简单的计算器

    Android实战教程第一篇之最简单的计算器

    这篇文章主要为大家详细介绍了Android实战教程第一篇,如何实现最简单的计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android Intent基础用法及作用详解

    Android Intent基础用法及作用详解

    Intent是一种重要的消息传递对象,用于在不同组件(如活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)等)之间进行通信和交互,本文介绍Android Intent基础用法及作用,感兴趣的朋友一起看看吧
    2024-07-07
  • Android中ViewPager带来的滑动卡顿问题解决要点解析

    Android中ViewPager带来的滑动卡顿问题解决要点解析

    这里我们主要针对ViewGroup的SwipeRefreshLayout中引入ViewPager所引起的滑动冲突问题进行讨论,一起来看一下Android中ViewPager带来的滑动卡顿问题解决要点解析:
    2016-06-06

最新评论