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
相关产品推荐
相关产品推荐

