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

Flutter WebView嵌入Iframe时,点击输入框触发键盘导致页面异常刷新且键盘不弹出

Flutter WebView嵌入Iframe时,点击输入框触发键盘导致页面异常刷新且键盘不弹出

看起来你遇到了webview_flutter嵌套iframe时的典型交互问题——点击输入框不仅唤不出键盘,还触发了页面刷新。我之前帮开发者排查过类似情况,结合你的代码,咱们一步步来解决:

先拆解下代码里可能的问题点:

  • 你给iframe设置了固定比例的height和width(基于初始化时的屏幕尺寸),当键盘弹出后屏幕可用高度缩小,这种固定尺寸会导致WebView内部布局紊乱,触发不必要的刷新;
  • 注释掉的NavigationDelegate可能漏掉了对iframe内部意外跳转的拦截;
  • build方法里的打印显示页面频繁重建,这和键盘弹出导致MediaQuery参数变化有关,但WebView本身不该因此重新加载内容。

方案1:优化iframe布局,避免固定尺寸冲突

把固定尺寸的iframe改成自适应WebView容器的布局,这样不管屏幕怎么变化(包括键盘弹出),布局都能保持稳定:

@override
void initState() {
  super.initState();
  Future.microtask(() {
    controller.loadRequest(Uri.dataFromString('''
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  <style>
    html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }
    iframe { width: 100%; height: 100%; border: none; }
  </style>
</head>
<body>
  <iframe src="${widget.url}"></iframe>
</body>
</html>
''', mimeType: 'text/html'));
  });
}

方案2:启用NavigationDelegate拦截意外跳转

重新启用NavigationDelegate,拦截iframe内部的非必要跳转,同时监控WebView加载状态:

final controller = WebViewController()
  ..setBackgroundColor(const Color(0x00000000))
  ..setNavigationDelegate(
    NavigationDelegate(
      onProgress: (int progress) {
        // 可添加加载进度提示
      },
      onPageStarted: (String url) {},
      onPageFinished: (String url) {},
      onWebResourceError: (WebResourceError error) {
        // 处理加载错误
      },
      onNavigationRequest: (NavigationRequest request) {
        // 只允许加载目标URL,拦截其他跳转
        if (request.url.startsWith(widget.url)) {
          return NavigationDecision.navigate;
        }
        return NavigationDecision.prevent;
      },
    ),
  );

方案3:防止State意外重建(可选)

如果页面还是频繁刷新,给State添加AutomaticKeepAliveClientMixin保留WebView状态:

class _PaymentWebViewState extends State<PaymentWebView> with AutomaticKeepAliveClientMixin {
  final controller = WebViewController()
    ..setBackgroundColor(const Color(0x00000000))
    ..setNavigationDelegate(
      NavigationDelegate(/* 你的配置 */),
    );

  @override
  bool get wantKeepAlive => true; // 开启状态保持

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必须调用此方法
    print("Refreshed webview");
    return Scaffold(
      body: WebViewWidget(controller: controller),
    );
  }

  // 其他代码不变...
}

方案4:升级webview_flutter到最新稳定版

旧版本的webview_flutter确实存在iframe交互的bug,比如输入框唤不起键盘、页面异常刷新等。在pubspec.yaml里升级依赖:

dependencies:
  webview_flutter: ^4.4.0 # 替换为当前最新稳定版本

升级后执行flutter pub get并重启应用。

备注:内容来源于stack exchange,提问作者Yassin Sameh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:57:59