Flutter中如何避免点击后重复弹出Alert Dialog?
Flutter 避免重复弹出Alert Dialog的正确实现
问题分析
你当前代码的核心问题在于:
didUserTouchedScreen = true是赋值操作而非判断,应该写成didUserTouchedScreen == true,但这个变量的逻辑本身无法可靠跟踪对话框状态_dialog变量绑定的是Future.delayed的结果,而非showDialog返回的Future,导致无法正确判断对话框是否处于打开状态
修正方案
我们直接利用showDialog返回的Future来跟踪对话框的显示状态,确保同一时间只会弹出一个对话框:
// 用这个变量跟踪对话框的Future,判断是否正在显示 Future? _activeDialog; Future<void> _checkTimer() async { // 如果没有正在显示的对话框,才执行后续逻辑 if (_activeDialog == null) { // 等待5秒后弹出对话框 await Future.delayed(const Duration(seconds: 5)); // 弹出对话框,并将返回的Future赋值给_activeDialog _activeDialog = showTimer(context); // 等待对话框关闭 await _activeDialog; // 对话框关闭后,重置变量 _activeDialog = null; } } Future<void> showTimer(BuildContext context) { // 这里判断用户是否触发了屏幕触摸(注意用==判断) if (didUserTouchedScreen == true) { final alert = Container(child: _imageslideshowProductDetailstimer()); // showDialog返回一个Future,对话框关闭时会完成 return showDialog( barrierDismissible: true, context: context, builder: (BuildContext context) { return WillPopScope( onWillPop: () async { didUserTouchedScreen = false; return true; }, child: alert, ); }, ).then((_) { didUserTouchedScreen = false; }); } // 如果条件不满足,返回一个已完成的Future return Future.value(); }
点击事件处理优化
你的点击事件中同时在onTapDown和onTapCancel调用_checkTimer,会导致重复触发,建议调整为:
behavior: HitTestBehavior.translucent, onTapDown: (tapdown) { print("down"); didUserTouchedScreen = true; }, onTapUp: (tapup) { print("up"); _checkTimer(); }, onTapCancel: () { print("cancel"); didUserTouchedScreen = false; }
关键逻辑说明
_activeDialog变量持有当前打开的对话框的Future,只要这个Future未完成,就说明对话框还在显示,不会触发新的弹出showDialog返回的Future会在对话框关闭(无论是用户点击返回、点击屏障还是其他方式)时完成,此时我们重置_activeDialog,允许后续再次弹出- 修正了
didUserTouchedScreen的判断逻辑,确保只有在用户确实触摸屏幕时才弹出对话框
内容的提问来源于stack exchange,提问作者newcomer
相关产品推荐
相关产品推荐

