flutter優(yōu)雅實現(xiàn)掃碼槍獲取數(shù)據(jù)源示例詳解
前言
在往期的分享中,小編介紹了如何通過 flutter 自帶的 EditableText 實現(xiàn)掃碼槍數(shù)據(jù)源的獲取。大致實現(xiàn)如下:
- 掃碼槍本質(zhì)上是一個外接的輸入設(shè)備。
- 使用 Stack 結(jié)合自己的布局控件 childWidget 將 editableText 封裝,控制隱藏??赏ㄟ^監(jiān)聽 onSubmitted 獲取掃碼槍的輸入內(nèi)容。
痛點問題
回顧 往期分享 痛點問題 :
使用 EditableText 的過程中遇到了系統(tǒng)鍵盤彈出的問題。我們通過 Edit 的焦點來獲取掃碼槍的輸入。但 EditableText 一旦獲取了焦點,內(nèi)部會調(diào)用原生層喚起鍵盤。
掃碼槍觸發(fā)焦點后,系統(tǒng)鍵盤自動彈起。這樣的失敗交互困擾了小編很久。
- 往期分享中的臨時方案 之前的處理方式是通過定制化源碼的方式,將指定版本內(nèi)的
TextInput.show手動注釋掉。
PS:這是一個笨方法,只能解燃眉之急,輸入框和文本,一直都是官方每個版本改動的重點。指定版本不是長久的方案。
如何在不改動源碼的方式下,動態(tài)控制焦點是否觸發(fā)鍵盤彈出?
1.系統(tǒng)鍵盤彈出的原因
實際上,系統(tǒng)鍵盤是否彈出,完全是因為 SystemChannels.textInput.invokeMethod<void>('TextInput.show') 的調(diào)用,但是我們不可能去每個調(diào)用該方法地方去做處理,那么這個方法執(zhí)行后續(xù),我們有辦法攔截嗎? 答案當(dāng)然是有的。
2. 如何攔截 methodChannel
Flutter 的 Framework 層發(fā)送信息 TextInput.show 到 Flutter 引擎是通過 MethodChannel, 而我們可以通過重載 WidgetsFlutterBinding 的 createBinaryMessenger 方法來處理Flutter 的 Framework 層通過 MethodChannel 發(fā)送的信息。
具體代碼如下:
使用 mixin 對 WidgetsFlutterBinding 進(jìn)行方法重載
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 進(jìn)行自定義攔截操作
class TextInputBinaryMessenger extends BinaryMessenger {
TextInputBinaryMessenger(this.origin);
final BinaryMessenger origin;
// Flutter 的 Framework 層發(fā)送信息到 Flutter 引擎,會走這個方法
@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 引擎,會走這個方法,這也是我們需要的處理的方法。
3. 攔截思路
可以根據(jù)我們的需求處理 send 方法了。當(dāng) channel 為 SystemChannels.textInput 的時候,根據(jù)方法名字來攔截 TextInput.show。
再定義一個特別的 FocusNode,并且定義好一個屬性用于判斷(也有那種需要隨時改變是否需要攔截信息的需求)。例如 TextInputFocusNode:
import 'package:flutter/material.dart';
class TextInputFocusNode extends FocusNode {
bool ignoreSystemKeyboardShow = true;
}
根據(jù)思路,我們的攔截方法實現(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é)點,嵌套使用:
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é)點 - scanNode:
- 非必傳,如果傳,可通過
scanNode監(jiān)聽獲取當(dāng)前掃碼可用狀態(tài),hasFocus時為可用 - 也可通過
scanNoderequestFocus 方法,強制掃碼獲取焦點,保證掃碼能力
- textFiledNode:
提供外部存在輸入框鍵盤輸入與掃碼輸入同時存在的場景。內(nèi)部做了焦點切換能力,保證輸入框焦點取消后,能馬上切換成掃碼槍的焦點

以上就是flutter優(yōu)雅實現(xiàn)掃碼槍獲取數(shù)據(jù)源示例詳解的詳細(xì)內(nèi)容,更多關(guān)于flutter掃碼槍獲取數(shù)據(jù)源的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析案例分享
這篇文章主要為大家介紹了安卓逆向騰訊動漫app返回數(shù)據(jù)加密分析的案例分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
android編程實現(xiàn)添加文本內(nèi)容到sqlite表中的方法
這篇文章主要介紹了android編程實現(xiàn)添加文本內(nèi)容到sqlite表中的方法,結(jié)合實例較為詳細(xì)的分析了Android針對txt文本文件的讀取及SQL數(shù)據(jù)庫操作的相關(guān)技巧,需要的朋友可以參考下2015-11-11
Android使用SAX解析XML格式數(shù)據(jù)的操作步驟
SAX是一種基于事件驅(qū)動的 XML 解析方式,適用于處理大規(guī)模 XML 文檔,本文給大家介紹了Android使用SAX解析XML格式數(shù)據(jù)的操作步驟,并通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-04-04
Android 啟動另一個App/apk中的Activity實現(xiàn)代碼
這篇文章主要介紹了Android 啟動另一個App/apk中的Activity實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04

