文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-01-11 12:00

关注

前言

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

痛点问题

回顾 往期分享 痛点问题 :

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

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

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);
  }

扫码库更新

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

dependencies:
  scan_gun: ^2.0.0
  ScanMonitorWidget({
    Key? key,
    required ChildBuilder childBuilder,
    TextInputFocusNode? scanNode,
    FocusNode? textFiledNode,
    required void Function(String) onSubmit,
  })
 void main() {
   TextInputBinding();
   runApp(const MyApp());
 }

参数说明:

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯