You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter InAppWebView:输入框获焦时禁用软键盘

Flutter InAppWebView:输入框获焦时禁用软键盘

嘿,这个需求我之前刚好踩过坑,分享几个实用的方案给你,应该能解决你的问题:

方案一:JS注入 + Flutter端联动(跨平台通用)

这个方案是我最常用的,核心思路是区分输入框聚焦的触发来源——是用户主动触摸,还是扫码程序触发的,然后分别处理:

  1. 注入JS监听输入事件
    在网页加载完成后,给网页里的所有输入框添加事件监听,标记是否是用户主动触摸触发的聚焦。在InAppWebView的onLoadStop回调里执行这段代码:

    await controller.evaluateJavascript(source: """
      let isUserTouchInitiated = false;
      // 给所有输入框绑定触摸事件,标记用户主动操作
      document.querySelectorAll('input').forEach(input => {
        input.addEventListener('touchstart', () => {
          isUserTouchInitiated = true;
        });
        // 监听聚焦事件,根据标记决定是否阻止键盘弹出
        input.addEventListener('focus', (e) => {
          if (!isUserTouchInitiated) {
            // 非用户触发的聚焦,调用Flutter端方法隐藏键盘
            setTimeout(() => {
              window.flutter_inappwebview.callHandler('hideKeyboard');
            }, 0);
          }
          // 重置标记,避免影响下一次操作
          isUserTouchInitiated = false;
        });
      });
    """);
    
  2. Flutter端注册键盘隐藏回调
    在onWebViewCreated里给WebView注册一个JS调用的handler,用来接收网页的隐藏键盘请求:

    controller.addJavaScriptHandler(
      handlerName: 'hideKeyboard',
      callback: (args) {
        // 通过系统通道隐藏软键盘
        SystemChannels.textInput.invokeMethod('TextInput.hide');
      },
    );
    
  3. 扫码时的输入处理
    当扫码完成后,直接通过JS给目标输入框赋值,哪怕触发聚焦,因为标记是false,也会自动隐藏键盘:

    // 替换成你的扫码结果和输入框选择器
    final scannedBarcode = "123456789";
    await controller.evaluateJavascript(source: """
      const targetInput = document.querySelector('#your-input-id');
      targetInput.value = '$scannedBarcode';
      // 如果需要保持输入框聚焦状态
      targetInput.focus();
    """);
    

方案二:Android端原生回调控制(仅Android)

如果你的APP只需要适配Android,可以直接用InAppWebView提供的原生回调,更直接:

你需要维护一个标记变量(比如isScanning),扫码前设为true,扫码完成后重置为false,然后在androidOnRequestFocus回调里判断:

InAppWebView(
  androidOnRequestFocus: (controller, view) async {
    // 如果是扫码触发的焦点请求,拦截并自己处理,不弹出键盘
    if (isScanning) {
      return true;
    }
    // 用户主动触摸的,交给系统处理,弹出键盘
    return false;
  },
  // 其他WebView配置...
)

这个方案缺点是只支持Android,iOS需要单独处理,所以如果是跨平台项目,还是方案一更稳妥。

方案三:替换为Flutter原生输入框(如果可行)

如果你有权限修改网页内容,或者可以用混合布局把网页里的输入区域换成Flutter的TextField,那控制起来会更简单:

  • 把网页输入框换成Flutter的TextField,默认设置readOnly: true,这样扫码赋值时不会弹出键盘;
  • 给TextField添加点击事件,点击时设置readOnly: false并自动弹出键盘,满足用户手动输入的需求。

不过这个方案的前提是你能修改网页布局,要是网页是第三方的没法改,就只能用前两个方案啦。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 08:23:07