flutter优雅实现扫码枪获取数据源示例详解

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

前言

在往期的分享中,小编介绍了如何通过 flutter 自带的 EditableText 实现扫码枪数据源的获取。大致实现如下:

  • 扫码枪本质上是一个外接的输入设备。
  • 使用 Stack 结合自己的布局控件 childWidgeteditableText 封装,控制隐藏。可通过监听 onSubmitted 获取扫码枪的输入内容。

痛点问题

回顾 往期分享 痛点问题 :

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

扫码枪触发焦点后,系统键盘自动弹起。这样的失败交互困扰了小编很久。

  • 往期分享中的临时方案 之前的处理方式是通过定制化源码的方式,将指定版本内的 TextInput.show 手动注释掉。

PS:这是一个笨方法,只能解燃眉之急,输入框和文本,一直都是官方每个版本改动的重点。指定版本不是长久的方案。

如何在不改动源码的方式下,动态控制焦点是否触发键盘弹出?

1.系统键盘弹出的原因

实际上,系统键盘是否弹出,完全是因为 SystemChannels.textInput.invokeMethod<void>('TextInput.show') 的调用,但是我们不可能去每个调用该方法地方去做处理,那么这个方法执行后续,我们有办法拦截吗? 答案当然是有的。

2. 如何拦截 methodChannel

Flutter 的 Framework 层发送信息 TextInput.show 到 Flutter 引擎是通过 MethodChannel, 而我们可以通过重载 WidgetsFlutterBindingcreateBinaryMessenger 方法来处理Flutter 的 Framework 层通过 MethodChannel 发送的信息。

具体代码如下:

使用 mixin 对 WidgetsFlutterBinding 进行方法重载

mixin TextInputBindingMixin on WidgetsFlutterBinding {
  @override
  BinaryMessenger createBinaryMessenger() {
    return TextInputBinaryMessenger(super.createBinaryMessenger());
  }
}

在 main 方法中初始化这个 binding

class TextInputBinding extends WidgetsFlutterBinding with TextInputBindingMixin {}
 void main() {
   TextInputBinding();
   runApp(const MyApp());
 }

自定义 TextInputBinaryMessager 对 methodChannel 进行自定义拦截操作

class TextInputBinaryMessenger extends BinaryMessenger {
  TextInputBinaryMessenger(this.origin);
  final BinaryMessenger origin;
  // Flutter 的 Framework 层发送信息到 Flutter 引擎,会走这个方法
  @override
  Future<ByteData?>? send(
    String channel,
    ByteData? message,
  ) {
    //TODO  拦截处理
  }
  // Flutter 引擎 发送信息到 Flutter 的 Framework 层的回调,无需处理
  @override
  void setMessageHandler(
    String channel,
    MessageHandler? handler,
  ) {
    ... 省略
  }
  //无需处理
  @override
  Future<void> handlePlatformMessage(
    String channel,
    ByteData? data,
    PlatformMessageResponseCallback? callback,
  ) {
    ... 省略
  }
}

send 方法:flutter 的 framework 层发送信息到 flutter 引擎,会走这个方法,这也是我们需要的处理的方法。

3. 拦截思路

可以根据我们的需求处理 send 方法了。当 channelSystemChannels.textInput 的时候,根据方法名字来拦截 TextInput.show

再定义一个特别的 FocusNode,并且定义好一个属性用于判断(也有那种需要随时改变是否需要拦截信息的需求)。例如 TextInputFocusNode

import 'package:flutter/material.dart';
class TextInputFocusNode extends FocusNode {
  bool ignoreSystemKeyboardShow = true;
}

根据思路,我们的拦截方法实现如下:

@override
  Future<ByteData?>? send(
    String channel,
    ByteData? message,
  ) {
    if (channel == SystemChannels.textInput.name) {
      final methodCall = SystemChannels.textInput.codec.decodeMethodCall(
        message,
      );
      switch (methodCall.method) {
        case 'TextInput.show':
          final FocusNode? focus = FocusManager.instance.primaryFocus;
          if (focus != null &&
              focus is TextInputFocusNode &&
              focus.ignoreSystemKeyboardShow) {
            return Future.value(
              SystemChannels.textInput.codec.encodeSuccessEnvelope(null),
            );
          }
          break;
        default:
          break;
      }
    }
    return origin.send(channel, message);
  }

扫码库更新

小编已将本次的方案调整重新发布上传,使用方式如下:

  • 在pubspec.yaml文件中进行引用
dependencies:
  scan_gun: ^2.0.0
  • 提供 ScanMonitorWidget 作为父节点,嵌套使用:
  ScanMonitorWidget({
    Key? key,
    required ChildBuilder childBuilder,
    TextInputFocusNode? scanNode,
    FocusNode? textFiledNode,
    required void Function(String) onSubmit,
  })
  • 在 main 方法中初始化 TextInputBinding
 void main() {
   TextInputBinding();
   runApp(const MyApp());
 }

参数说明:

  • childBuilder : typedef ChildBuilder = Widget Function(BuildContext context),使用者自己UI作为子节点
  • scanNode:
  • 非必传,如果传,可通过 scanNode 监听获取当前扫码可用状态,hasFocus 时为可用
  • 也可通过 scanNode requestFocus 方法,强制扫码获取焦点,保证扫码能力
  • textFiledNode:
    提供外部存在输入框键盘输入与扫码输入同时存在的场景。内部做了焦点切换能力,保证输入框焦点取消后,能马上切换成扫码枪的焦点

以上就是flutter优雅实现扫码枪获取数据源示例详解的详细内容,更多关于flutter扫码枪获取数据源的资料请关注脚本之家其它相关文章!

相关文章

  • Android中异步类AsyncTask用法总结

    Android中异步类AsyncTask用法总结

    这篇文章主要介绍了Android中异步类AsyncTask用法,分析总结了Async Task类的功能、特点及相关的使用技巧与注意事项,需要的朋友可以参考下
    2016-01-01
  • Android通过Path实现搜索按钮和时钟复杂效果

    Android通过Path实现搜索按钮和时钟复杂效果

    这篇文章主要为大家详细介绍了Android通过Path实现搜索按钮和时钟复杂效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • Android View滑动的实现分析示例

    Android View滑动的实现分析示例

    View滑动是Android实现自定义控件的基础,同时在开发中难免会遇到View的滑动处理,其实不管是那种滑动方法,基本思路是类似的;当点击事件传到View时,系统记下触摸点的坐标,手指移动时系统记下移动后的左边并算出偏移量,通过偏移量来修改View的坐标
    2022-08-08
  • Android中的Bmob移动后端云服务器功能

    Android中的Bmob移动后端云服务器功能

    这里介绍一个移动后端云服务器平台bmob,这不仅可以实现云数据库储存,还可以获取手机验证等,随时随地都很轻松,下面写一个小demo,实现一个登陆注册功能,认识增删查改
    2018-01-01
  • Android 遍历文件夹中所有文件的实例代码

    Android 遍历文件夹中所有文件的实例代码

    本篇文章主要介绍了Android 遍历文件夹中所有文件的实例代码,可以获得文件夹中所有文件的路径及文件名,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-06-06
  • Android开发实现拍照功能的方法实例解析

    Android开发实现拍照功能的方法实例解析

    这篇文章主要介绍了Android开发实现拍照功能的方法,结合实例形式较为详细的分析了Android拍照功能的具体实现步骤与相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • Android边播放边缓存视频框架AndroidVideoCache详解

    Android边播放边缓存视频框架AndroidVideoCache详解

    这篇文章主要为大家介绍了Android边播放边缓存视频框架AndroidVideoCache详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Android封装对原生Log进行封装的操作

    Android封装对原生Log进行封装的操作

    这篇文章主要介绍了Android封装对原生Log进行封装的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Android判断用户是否允许了摄像头权限实例代码

    Android判断用户是否允许了摄像头权限实例代码

    本篇文章主要介绍了Android判断用户是否允许了摄像头权限实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Android控件Spinner实现下拉列表及监听功能

    Android控件Spinner实现下拉列表及监听功能

    这篇文章主要介绍了Android控件Spinner实现下拉列表及监听功能,这是在Web开发中一个必不可少的交互性组件,而在Android中的对应实现就是Spinner。需要的朋友可以参考下
    2018-07-07

最新评论