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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:45:01