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

Flutter WebView无AppBar时如何启用手机物理返回键返回上一页而不退出应用

解决Flutter WebView物理返回键无法回退网页的方案

问题根因

你之前使用WillPopScope无效大概率是两个原因:

  • Flutter 3.16及以上版本已正式废弃WillPopScope组件,替换为PopScope
  • 没有在返回拦截逻辑中正确判断WebView当前的导航栈状态,没有优先触发网页回退

实现步骤

1. 确认依赖

首先确保pubspec.yaml中已引入官方WebView组件:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.4.0 # 建议使用4.0以上稳定版

2. 核心代码实现

适配Flutter 3.16+ 版本(推荐)

使用PopScope组件拦截返回事件,结合WebViewController的导航栈判断实现逻辑:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewPage extends StatefulWidget {
  final String url;
  const WebViewPage({super.key, required this.url});

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  late final WebViewController _webViewController;

  @override
  void initState() {
    super.initState();
    // 初始化WebViewController
    _webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse(widget.url));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 不需要设置AppBar即可生效
      body: PopScope(
        // 核心拦截逻辑
        onPopInvoked: (didPop) async {
          // 如果系统已经执行了pop操作,直接返回
          if (didPop) return;
          // 判断WebView是否可以回退上一级网页
          if (await _webViewController.canGoBack()) {
            // 执行网页回退
            await _webViewController.goBack();
          } else {
            // 网页无回退栈时,执行系统返回逻辑(退出当前页面/应用)
            if (mounted) {
              Navigator.of(context).pop();
            }
          }
        },
        child: WebViewWidget(controller: _webViewController),
      ),
    );
  }
}

适配Flutter 3.16以下旧版本

如果你使用的Flutter版本低于3.16,可使用如下WillPopScope的正确写法:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: WillPopScope(
      onWillPop: () async {
        if (await _webViewController.canGoBack()) {
          await _webViewController.goBack();
          // 返回false表示拦截当前返回事件,不执行系统pop
          return false;
        }
        // 返回true表示执行系统默认返回逻辑
        return true;
      },
      child: WebViewWidget(controller: _webViewController),
    ),
  );
}

注意事项

  • 确保WebViewController初始化完成后再调用canGoBack方法,避免空异常
  • 如果网页内有自定义的路由跳转逻辑,需确保JavaScript权限已开启,否则会导致网页导航栈识别异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:27:04