Android 上的 Flutter:键盘监听器和文本输入字段

问题描述 投票:0回答:1

我们不是 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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
android flutter dart
1个回答
0
投票

如果您使用全局状态管理解决方案,请验证状态更改不会无意中影响屏幕键盘的可见性或焦点,并确保在离开屏幕时正确处理小部件。如果小部件保留在小部件树中,它们可能仍在侦听事件或维护干扰键盘行为的状态。 还要小心不必要的状态更新,这可能会触发重建并影响焦点或键盘可见性。

© www.soinside.com 2019 - 2024. All rights reserved.