Flutter WebView返回按钮逻辑异常:单次点击同时触发返回与提示
解决方案:Flutter WebView返回按钮逻辑修复
问题根源
原代码未区分WebView回退状态与应用退出逻辑,两个独立的if分支会在首次点击时同时触发回退操作与退出提示;同时使用全局变量维护状态,易引发多页面状态混乱。
修正代码
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:webview_flutter/webview_flutter.dart'; final uri = Uri.parse('https://google.com'); class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { late WebViewController controller; int _backPressCount = 0; DateTime? _lastPressTime; @override void initState() { super.initState(); controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate(NavigationDelegate( onPageFinished: (String url) { print(url); }, )) ..loadRequest(uri); } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvoked: (didPop) async { DateTime now = DateTime.now(); // 优先处理WebView回退逻辑 bool canGoBack = await controller.canGoBack(); if (canGoBack) { controller.goBack(); // 重置退出计数 setState(() { _backPressCount = 0; _lastPressTime = null; }); return; } // WebView无法回退时,处理应用退出逻辑 if (_lastPressTime != null && now.difference(_lastPressTime!) > const Duration(seconds: 3)) { setState(() { _backPressCount = 0; }); } setState(() { _backPressCount++; _lastPressTime = now; }); if (_backPressCount == 2) { // 双击显示退出提示 ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('再点击一次退出应用'), ), ); } else if (_backPressCount >= 3) { // 三次点击退出应用 SystemNavigator.pop(); exit(0); } }, child: Scaffold( floatingActionButton: Container( height: 40.0, width: 40.0, child: FittedBox( child: FloatingActionButton( child: const Icon(Icons.arrow_back), onPressed: () async { bool canGoBack = await controller.canGoBack(); if (canGoBack) { controller.goBack(); setState(() { _backPressCount = 0; _lastPressTime = null; }); } else { // 触发系统返回逻辑 Navigator.maybePop(context); } }, backgroundColor: Colors.grey.shade200, ), ), ), body: SafeArea( child: WebViewWidget( controller: controller, ), ), ), ); } }
关键修改点
- 状态管理优化:将
StatelessWidget改为StatefulWidget,使用状态变量_backPressCount和_lastPressTime维护点击状态,避免全局变量污染。 - 逻辑优先级调整:先判断WebView是否可回退,仅当无法回退时才处理应用退出逻辑,彻底解决单击时回退与提示同时触发的问题。
- 退出逻辑明确:
- WebView可回退:单击返回上一页,重置退出计数。
- WebView不可回退:第一次单击无提示,第二次单击显示退出提示,第三次单击(3秒内)退出应用。
- 浮动按钮同步逻辑:自定义返回按钮与系统返回按钮行为保持一致,确保交互统一。
内容的提问来源于stack exchange,提问作者gill
相关产品推荐
相关产品推荐

