flutter实现扫码枪获取数据源禁止系统键盘弹窗示例详解
作者:李小轰_Rex 发布时间:2023-07-23 01:52:41
序言
小编在项目中有遇到使用 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();
}
}
来源:https://juejin.cn/post/7163845736411430920
猜你喜欢
- 在学会了java中io流的使用后,我们对于数组的排序,又多了一种使用方法。大家知道流处理数据的效率是比较理想的,那么在具体操作数组排序上,很
- Rsa加密RSA是目前最有影响力的公钥加密算法,RSA也是第一个既能用于数据加密也能用于数字签名的算法。该算法基于一个十分简单的数论事实:将
- Unity IPostBuildPlayerScriptDLLsUnity IPostBuildPlayerScriptDLLs是Unity
- 过滤器实现过滤器需要实现 javax.servlet.Filter 接口。重写三个方法。其中 init()&n
- 接上文Spring Cloud下基于OAUTH2认证授权的实现,我们将基于Spring Cloud实现OAUTH2的注销功能。1 增加自定义
- 前言很多时候,我们定义接口或者调用别人的接口时,手里只有一份接口文档,文档中提供一段示例json格式的报文,我们需要根据json中的字段,挨
- 前言在项目的开发时,遇到实现服务器主动发送数据到前端页面的功能的需求。实现该功能不外乎使用轮询和websocket技术,但在考虑
- 一、概述System.Net.WebClient属于高层类、使用简单。均支持异步版本。支持http,https,fpt,files等URI。
- 前言最近项目中又一次需要集成友盟的三方登录与分享,之前没有记录过,所以这次来写一下...准备工作1.注册友盟账号创建应用,获取key:申请地
- 编辑上传文件的页面upload.html注意事项:上传方式使用POST不能使用GET(GET不能上传文件)表单 enctype 属性应该设置
- 本文实例讲述了Android编程判断SD卡是否存在及使用容量查询实现方法。分享给大家供大家参考,具体如下:1.判断SD卡是否存在 返回tru
- 需要的jar包:数据库代码:create database school character set utf8;use school;CRE
- 1. 简单工厂介绍简单工厂有一个具体的工厂类,可以生产不同的产品,属于创建型设计模式。注意:简单工厂模式 不属于23种设计模式之列2. 简单
- 在Scala中调用java的方法,很简单,直接导入传递参数就可以进行调用了.在Java中调用Scala的方法呢?经过测试,也是很简单,静态方
- 在前面的《基于任务的异步编程模式(TAP)》文章中讲述了.net 4.5框架下的异步操作自我实现方式,实际上,在.net 4.5中部分类已实
- Activator.CreateInstance和AssemblyCreateInstance性能测试using System;using
- 前两天发现 idea 终于更新了2020.1版本,新增了好多的特性,这里不介绍,主要写一下中文插件的安装首先下载新版 安装包 https:/
- 前言Windows 11下所有控件已经默认采用圆角,其效果更好、相对有着更好的优化,只是这是默认的行为,无法进一步自定义。圆角按钮实现【重写
- 首先来看效果: 一、实现原理在实现过程中,主要考虑整个界面由若干个字母组成的子母线条组成,这样的话把固定数量的字母封装成一个字母线条,而每个
- Android 中下拉菜单,即如html中的<select>,关键在于调用setDropDownViewResource方法,以