亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

flutter優(yōu)雅實(shí)現(xiàn)掃碼槍獲取數(shù)據(jù)源示例詳解

 更新時(shí)間:2023年01月11日 09:48:03   作者:李小轟_Rex  
這篇文章主要為大家介紹了flutter優(yōu)雅實(shí)現(xiàn)掃碼槍獲取數(shù)據(jù)源示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在往期的分享中,小編介紹了如何通過 flutter 自帶的 EditableText 實(shí)現(xiàn)掃碼槍數(shù)據(jù)源的獲取。大致實(shí)現(xiàn)如下:

  • 掃碼槍本質(zhì)上是一個(gè)外接的輸入設(shè)備。
  • 使用 Stack 結(jié)合自己的布局控件 childWidgeteditableText 封裝,控制隱藏??赏ㄟ^監(jiān)聽 onSubmitted 獲取掃碼槍的輸入內(nèi)容。

痛點(diǎn)問題

回顧 往期分享 痛點(diǎn)問題 :

使用 EditableText 的過程中遇到了系統(tǒng)鍵盤彈出的問題。我們通過 Edit 的焦點(diǎn)來獲取掃碼槍的輸入。但 EditableText 一旦獲取了焦點(diǎn),內(nèi)部會(huì)調(diào)用原生層喚起鍵盤。

掃碼槍觸發(fā)焦點(diǎn)后,系統(tǒng)鍵盤自動(dòng)彈起。這樣的失敗交互困擾了小編很久。

  • 往期分享中的臨時(shí)方案 之前的處理方式是通過定制化源碼的方式,將指定版本內(nèi)的 TextInput.show 手動(dòng)注釋掉。

PS:這是一個(gè)笨方法,只能解燃眉之急,輸入框和文本,一直都是官方每個(gè)版本改動(dòng)的重點(diǎn)。指定版本不是長久的方案。

如何在不改動(dòng)源碼的方式下,動(dòng)態(tài)控制焦點(diǎn)是否觸發(fā)鍵盤彈出?

1.系統(tǒng)鍵盤彈出的原因

實(shí)際上,系統(tǒng)鍵盤是否彈出,完全是因?yàn)?SystemChannels.textInput.invokeMethod<void>('TextInput.show') 的調(diào)用,但是我們不可能去每個(gè)調(diào)用該方法地方去做處理,那么這個(gè)方法執(zhí)行后續(xù),我們有辦法攔截嗎? 答案當(dāng)然是有的。

2. 如何攔截 methodChannel

Flutter 的 Framework 層發(fā)送信息 TextInput.show 到 Flutter 引擎是通過 MethodChannel, 而我們可以通過重載 WidgetsFlutterBindingcreateBinaryMessenger 方法來處理Flutter 的 Framework 層通過 MethodChannel 發(fā)送的信息。

具體代碼如下:

使用 mixin 對 WidgetsFlutterBinding 進(jìn)行方法重載

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

在 main 方法中初始化這個(gè) binding

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

自定義 TextInputBinaryMessager 對 methodChannel 進(jìn)行自定義攔截操作

class TextInputBinaryMessenger extends BinaryMessenger {
  TextInputBinaryMessenger(this.origin);
  final BinaryMessenger origin;
  // Flutter 的 Framework 層發(fā)送信息到 Flutter 引擎,會(huì)走這個(gè)方法
  @override
  Future<ByteData?>? send(
    String channel,
    ByteData? message,
  ) {
    //TODO  攔截處理
  }
  // Flutter 引擎 發(fā)送信息到 Flutter 的 Framework 層的回調(diào),無需處理
  @override
  void setMessageHandler(
    String channel,
    MessageHandler? handler,
  ) {
    ... 省略
  }
  //無需處理
  @override
  Future<void> handlePlatformMessage(
    String channel,
    ByteData? data,
    PlatformMessageResponseCallback? callback,
  ) {
    ... 省略
  }
}

send 方法:flutter 的 framework 層發(fā)送信息到 flutter 引擎,會(huì)走這個(gè)方法,這也是我們需要的處理的方法。

3. 攔截思路

可以根據(jù)我們的需求處理 send 方法了。當(dāng) channelSystemChannels.textInput 的時(shí)候,根據(jù)方法名字來攔截 TextInput.show

再定義一個(gè)特別的 FocusNode,并且定義好一個(gè)屬性用于判斷(也有那種需要隨時(shí)改變是否需要攔截信息的需求)。例如 TextInputFocusNode

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

根據(jù)思路,我們的攔截方法實(shí)現(xiàn)如下:

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

掃碼庫更新

小編已將本次的方案調(diào)整重新發(fā)布上傳,使用方式如下:

  • 在pubspec.yaml文件中進(jìn)行引用
dependencies:
  scan_gun: ^2.0.0
  • 提供 ScanMonitorWidget 作為父節(jié)點(diǎn),嵌套使用:
  ScanMonitorWidget({
    Key? key,
    required ChildBuilder childBuilder,
    TextInputFocusNode? scanNode,
    FocusNode? textFiledNode,
    required void Function(String) onSubmit,
  })
  • 在 main 方法中初始化 TextInputBinding
 void main() {
   TextInputBinding();
   runApp(const MyApp());
 }

參數(shù)說明:

  • childBuilder : typedef ChildBuilder = Widget Function(BuildContext context),使用者自己UI作為子節(jié)點(diǎn)
  • scanNode:
  • 非必傳,如果傳,可通過 scanNode 監(jiān)聽獲取當(dāng)前掃碼可用狀態(tài),hasFocus 時(shí)為可用
  • 也可通過 scanNode requestFocus 方法,強(qiáng)制掃碼獲取焦點(diǎn),保證掃碼能力
  • textFiledNode:
    提供外部存在輸入框鍵盤輸入與掃碼輸入同時(shí)存在的場景。內(nèi)部做了焦點(diǎn)切換能力,保證輸入框焦點(diǎn)取消后,能馬上切換成掃碼槍的焦點(diǎn)

以上就是flutter優(yōu)雅實(shí)現(xiàn)掃碼槍獲取數(shù)據(jù)源示例詳解的詳細(xì)內(nèi)容,更多關(guān)于flutter掃碼槍獲取數(shù)據(jù)源的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論