Flutter WebView应用无网络打开时如何展示自定义离线提示页面
实现方案
整体思路是通过监听WebView的资源加载错误事件,配合状态变量切换WebView和自定义无网络Widget的显示,具体实现如下:
- 第一步:在State类中声明所需状态变量
- 第二步:使用
IndexedStack组件包裹WebView和自定义错误页,根据错误状态切换显示内容 - 第三步:给WebView添加
onWebResourceError回调,监听加载错误事件,触发时更新状态显示错误页 - 第四步:给自定义错误页添加重试逻辑,点击后重置状态并重新加载页面
完整示例代码
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; class MyWebViewPage extends StatefulWidget { const MyWebViewPage({super.key}); @override State<MyWebViewPage> createState() => _MyWebViewPageState(); } class _MyWebViewPageState extends State<MyWebViewPage> { bool _loadError = false; final Completer<WebViewController> _controllerCompleter = Completer<WebViewController>(); WebViewController? _controller; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("WebView示例")), body: IndexedStack( index: _loadError ? 1 : 0, children: [ // 正常状态显示WebView WebView( initialUrl: 'https://deoxy.tech/', javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) { _controllerCompleter.future.then((value) => _controller = value); _controllerCompleter.complete(webViewController); }, // 监听加载错误事件 onWebResourceError: (error) { // 可自行筛选错误类型,仅网络错误时显示自定义页 // 常见网络错误码:-2=域名无法解析、-7=连接超时、-102=连接被拒绝 if([-2, -7, -102].contains(error.errorCode)){ setState(() { _loadError = true; }); } }, // 页面开始加载时重置错误状态 onPageStarted: (url) { if(_loadError){ setState(() { _loadError = false; }); } }, ), // 错误状态显示自定义无网络页 Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.wifi_off, size: 64, color: Colors.grey), const SizedBox(height: 16), const Text("无网络连接", style: TextStyle(fontSize: 16, color: Colors.grey)), const SizedBox(height: 24), ElevatedButton( onPressed: () { setState(() { _loadError = false; }); _controller?.reload(); }, child: const Text("重试"), ) ], ), ) ], ), ); } }
补充说明
- 如果需要适配所有加载错误场景而非仅网络错误,去掉
onWebResourceError中的错误码判断即可,所有加载失败场景都会触发自定义错误页显示。 - 安卓端需要先在
android/app/src/main/AndroidManifest.xml中添加网络权限,否则会一直显示无网络错误:
<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者mishalhaneef
相关产品推荐
相关产品推荐

