我们不是 flutter 程序员,但是我们有一个外包团队为我们开发应用程序。不幸的是,他们无法解决这个问题,因此我们将其发布给更广泛的社区。
这里有一些背景知识:
我们的应用程序中有一个屏幕,应该接受来自外部条形码扫描仪的输入,然后使用扫描的条形码执行一些逻辑。当用户通过蓝牙扫描仪进行扫描时,我们不希望显示屏幕键盘,因此我们使用 KeyboardListener 来捕获输入,然后处理数据。
用户可以点击按钮以显示文本输入字段,并点击屏幕键盘以手动输入条形码(如果需要)。这将关闭 KeyboardListener 并将其替换为输入字段。他们可以再次点击按钮将其交换回来。
问题来了:
当应用程序冷启动时,如果用户通过应用程序导航到上述屏幕而不点击任何输入字段,则蓝牙扫描仪将工作并且不会显示屏幕键盘。
但是,如果在打开应用程序后的任何时间,用户在任何屏幕中点击输入字段,然后进入扫描屏幕并使用蓝牙扫描仪进行扫描,则屏幕键盘会向用户显示,即使有没有焦点的输入字段。如果我们添加代码来在从扫描仪接收到每个字符后抑制屏幕键盘,则每次击键时屏幕键盘都会上下闪烁。
我真的不知道程序员如何处理应用程序中的状态等,我们有一种感觉,当打开新页面和关闭页面时,小部件不会被破坏......不确定这是否相关。
我们已经尝试了网上能找到的所有方法,但没有成功。
我们还深入研究了https://github.com/flutter/flutter/issues/51478,flutter 表示他们已经解决了该问题,但我们正在运行最新的稳定版本 flutter 3.19.6,它仍然是一个问题。
下面是小部件代码,希望更有经验的人能够看到我们都缺少的明显东西。仅供参考,我们用非常基本的逻辑替换了 onKeyEvent 来记录按下的按键(即将控制器排除在等式之外),但问题仍然存在。
我们还注意到,“有时”当您切换到另一个应用程序然后返回到我们的应用程序时,问题会得到纠正,直到您点击另一个输入字段......并非总是如此,但有时??
Widget build(BuildContext context) {
return Container(
color: AppColors.primaryColor,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: size.width(15.0), vertical: size.height(5.0))
.copyWith(
bottom: MediaQuery.of(context).viewInsets.bottom +
size.height(5.0)),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 4,
child: SizedBox(
height: 40,
child: controller.isKeyboardOpen == false
? KeyboardListener(
focusNode: _focusNode,
autofocus: true,
onKeyEvent: (KeyEvent event) {
if (event is KeyDownEvent) {
if (event.logicalKey == LogicalKeyboardKey.enter) {
SystemChannels.textInput.invokeMethod('TextInput.hide');
controller.update();
controller.pickScanFunctionality(pickableLines);
} else {
controller.qtyScanningController.text += event.character ?? "";
print(event.character.toString() + " received");
}
}
} ,
child: SizedBox()
)
:
appTextField(
textEditingController: controller.qtyScanningController,
hintText: "Scan...",
enableInteractiveSelection: false,
focusNode: controller.pickScanFocusNode,
inputType: controller.isKeyboardOpen
? TextInputType.text
: TextInputType.none,
autoFocus: true,
onFieldSubmit: (value) {
controller.pickScanFunctionality(pickableLines);
},
onChanged: (value) {
return;
},
suffixIcon: GestureDetector(
onTap: () {
controller.qtyScanningController.clear();
},
child: const Icon(
Icons.close,
color: AppColors.lightBlueColor,
size: 20,
),
),
isReadOnly: false,//!controller.isKeyboardOpen,
showCursor: true,
hintTextStyle: const TextStyle(
color: AppColors.lightBlueColor,
fontSize: 14,
)),
),
),
size.widthSpace(10),
GestureDetector(
onTap: () {
Get.to(const BarcodeScanScreen());
Get.find<BarcodeScannerController>().isPickScanningBarcode =
true;
Get.find<BarcodeScannerController>().update();
},
child: Icon(
MdiIcons.barcode,
color: AppColors.whiteColor,
size: 40,
),
),
size.widthSpace(15),
GestureDetector(
onTap: () {
controller.isKeyboardOpen = !controller.isKeyboardOpen;
printData("isKeyBoard:: ${controller.isKeyboardOpen}");
controller.update();
},
child: const Icon(
Icons.keyboard_alt_outlined,
color: AppColors.whiteColor,
size: 30,
),
),
],
),
),
);
}
}
如果您使用全局状态管理解决方案,请验证状态更改不会无意中影响屏幕键盘的可见性或焦点,并确保在离开屏幕时正确处理小部件。如果小部件保留在小部件树中,它们可能仍在侦听事件或维护干扰键盘行为的状态。 还要小心不必要的状态更新,这可能会触发重建并影响焦点或键盘可见性。