Flutter WebView中WillPopScope异常,求修改onWillPop方法方案
修复WebView返回按钮逻辑问题
问题现状
当前点击返回按钮时,直接触发WillPopScope的退出确认对话框,未先尝试返回WebView的上一页,不符合网页浏览的常规逻辑。
修改方案
- 将
WebViewController和Completer改为类成员变量(避免在build方法内声明导致每次重建丢失引用) - 在
onWillPop中优先检查WebView是否存在历史记录:- 若可返回上一页,调用
goBack()并返回false阻止默认退出行为 - 若已处于首页,再弹出退出确认对话框
- 若可返回上一页,调用
修改后的完整代码示例
调整类成员变量
class YourWebViewPage extends StatefulWidget { final String homeURL; const YourWebViewPage({Key? key, required this.homeURL}) : super(key: key); @override State<YourWebViewPage> createState() => _YourWebViewPageState(); } class _YourWebViewPageState extends State<YourWebViewPage> { late WebViewController _controller; final Completer<WebViewController> _controllerCompleter = Completer<WebViewController>(); // 其他成员方法... }
修改onWillPop方法
onWillPop: () async { // 先检查WebView是否能返回上一页 if (await _controller.canGoBack()) { _controller.goBack(); return false; // 阻止默认退出行为 } else { // 无法返回时弹出确认对话框 showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: const Text("Xác nhận thoát"), content: const Text("Bạn có chắc bạn muốn thoát?"), actions: <Widget>[ TextButton( child: const Text("VÂNG"), onPressed: () { SystemNavigator.pop(); }, ), TextButton( child: const Text("KHÔNG"), onPressed: () { Navigator.of(context).pop(); }, ) ], ); } ); return false; // 由对话框操作处理退出逻辑 } },
调整build方法中的WebView初始化
@override Widget build(BuildContext context) { return WillPopScope( onWillPop: // 上述修改后的onWillPop方法 child: netState ? Scaffold( body: Padding( padding: const EdgeInsets.only(top: 32), child: WebView( initialUrl: widget.homeURL, zoomEnabled: false, userAgent: 'random', javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) { _controllerCompleter.complete(webViewController); _controller = webViewController; }, navigationDelegate: (NavigationRequest request) { if (request.url.startsWith(widget.homeURL) || request.url.contains("https://test-payment.momo.vn/") || request.url.contains("https://payment.momo.vn/") || request.url.startsWith("momo://app?action=payWithAppToken&amount=") || request.url.contains("google.com") || request.url.contains("facebook.com")) { return NavigationDecision.navigate; } else { _launchURL(request.url); return NavigationDecision.prevent; } }, ), ), ) : // 无网络状态下的UI组件 ); }
关键说明
- 类成员级别的
WebViewController是核心,确保能持续获取WebView的历史状态 canGoBack()方法用于检测WebView是否存在可返回的历史页面- 返回
false是为了拦截WillPopScope的默认退出流程,优先执行WebView的返回逻辑
内容的提问来源于stack exchange,提问作者Ram Gupta
相关产品推荐
相关产品推荐

