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

Flutter Android端WebView加载HTMLString后空白,需交互才显示

解决Android 14真机webview_flutter 4.9.0加载HTMLString空白问题

问题现象

在Android 14真机上,使用webview_flutter 4.9.0加载HTML字符串后,WebView会显示空白(颜色跟随系统主题),只有在触摸屏幕、旋转设备或按音量键等交互操作后,才会渲染并展示HTML内容。

解决方案

该问题源于Android 14下WebView初始渲染时机与Flutter页面生命周期不匹配,可通过以下两种方式修复:

方式1:在Widget渲染完成后加载HTML内容

利用WidgetsBinding.instance.addPostFrameCallback等待当前帧渲染完成后再加载HTML,确保WebView已完成初始化:

修改_WebViewPageState代码如下:

class _WebViewPageState extends State<WebViewPage> {
  late WebViewController webViewController;

  @override
  void initState() {
    super.initState();
    webViewController = WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted);
    
    // 当前帧渲染完成后加载HTML
    WidgetsBinding.instance.addPostFrameCallback((_) {
      webViewController
        ..loadHtmlString('''<!DOCTYPE html>
        <html lang='de-DE'>
          <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <style>
               div span, div p {
                  font-size: 16px !important;
               }
            </style>
          </head>
          <body style="overflow-wrap: break-word; word-wrap: break-word; white-space: normal;">
            ${widget.content}
            <script>
              console.log("js log")
            </script>
          </body>
        </html>''')
        ..platform.setOnConsoleMessage(onconsoleleLog);
    });
  }

  @override
  Widget build(BuildContext context){
    return Scaffold(
        appBar: AppBar(
            title: Text(
          (widget.title != null ? widget.title! : 'Inhalt'),
          maxLines: 1,
        )),
        body: WebViewWidget(
          controller: webViewController,
        ));
  }

  void onconsoleleLog(JavaScriptConsoleMessage consoleMessage) {
    print("BROWSER LOG: ${consoleMessage.message}");  
  }
}

方式2:延迟触发WebView重绘

如果方式1无效,可通过延迟更新状态触发WebView重绘:

class _WebViewPageState extends State<WebViewPage> {
  late WebViewController webViewController;
  bool _isWebViewReady = false;

  @override
  void initState() {
    super.initState();
    webViewController = WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted);
    
    webViewController.loadHtmlString('''<!DOCTYPE html>
        <html lang='de-DE'>
          <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <style>
               div span, div p {
                  font-size: 16px !important;
               }
            </style>
          </head>
          <body style="overflow-wrap: break-word; word-wrap: break-word; white-space: normal;">
            ${widget.content}
            <script>
              console.log("js log")
            </script>
          </body>
        </html>''')
        ..platform.setOnConsoleMessage(onconsoleleLog);
    
    // 延迟标记WebView就绪,触发重绘
    Future.delayed(const Duration(milliseconds: 100), () {
      if (mounted) {
        setState(() {
          _isWebViewReady = true;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context){
    return Scaffold(
        appBar: AppBar(
            title: Text(
          (widget.title != null ? widget.title! : 'Inhalt'),
          maxLines: 1,
        )),
        body: _isWebViewReady ? WebViewWidget(controller: webViewController) : const SizedBox.shrink());
  }

  void onconsoleleLog(JavaScriptConsoleMessage consoleMessage) {
    print("BROWSER LOG: ${consoleMessage.message}");  
  }
}

额外优化建议

  • 将HTML中initial-scale从0.2改为1.0,避免页面过度缩放;
  • 把font-size: 2vw改为固定值(如16px),提升移动端文本可读性;
  • 将WebViewController改为late初始化,避免提前初始化导致的上下文不匹配问题。

内容的提问来源于stack exchange,提问作者matrixPill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:32:32