.NET MAUI Android下TapGestureRecognizer双击重复打开页面的解决方法
解决MAUI Android双击Frame触发多次页面跳转的问题
Android平台下,绑定了TapGestureRecognizer的Frame控件在快速双击时会多次触发Tapped事件,导致多次调用PushModalAsync打开多个CircleOneSliderPage实例;而iOS平台自带事件防抖机制,无此问题。以下是几种可行的解决方案:
方案一:使用标志位阻止重复触发
在页面类中添加布尔变量标记导航状态,避免重复执行跳转逻辑:
首先添加一个扩展方法,用于等待页面关闭:
public static class PageExtensions { public static Task WaitForDisappearing(this Page page) { var tcs = new TaskCompletionSource<bool>(); void DisappearingHandler(object s, EventArgs e) { page.Disappearing -= DisappearingHandler; tcs.TrySetResult(true); } page.Disappearing += DisappearingHandler; return tcs.Task; } }
修改点击事件逻辑:
private bool _isNavigating = false; private async void CircleOneSliderPage_Tapped(object sender, TappedEventArgs e) { if (_isNavigating) return; _isNavigating = true; try { var targetPage = new CircleOneSliderPage(); await Shell.Current.Navigation.PushModalAsync(targetPage); await targetPage.WaitForDisappearing(); } catch (Exception ex) { await DisplayAlert("Error", ex.Message, "OK"); } finally { _isNavigating = false; } }
方案二:检查导航栈是否已存在目标页面
跳转前检查模态导航栈中是否已有CircleOneSliderPage实例,存在则不重复打开:
private async void CircleOneSliderPage_Tapped(object sender, TappedEventArgs e) { try { // 遍历模态导航栈,查找是否已有目标页面实例 var existingPage = Shell.Current.Navigation.ModalStack.FirstOrDefault(p => p is CircleOneSliderPage); if (existingPage != null) return; await Shell.Current.Navigation.PushModalAsync(new CircleOneSliderPage()); } catch (Exception ex) { await DisplayAlert("Error", ex.Message, "OK"); } }
方案三:临时禁用手势识别器
点击触发后先禁用TapGestureRecognizer,待页面关闭后重新启用:
先给XAML中的手势识别器命名:
<TapGestureRecognizer x:Name="CircleOneTap" NumberOfTapsRequired="1" Tapped="CircleOneSliderPage_Tapped" />
修改点击事件逻辑(需搭配方案一中的WaitForDisappearing扩展方法):
private async void CircleOneSliderPage_Tapped(object sender, TappedEventArgs e) { try { CircleOneTap.IsEnabled = false; var targetPage = new CircleOneSliderPage(); await Shell.Current.Navigation.PushModalAsync(targetPage); await targetPage.WaitForDisappearing(); } catch (Exception ex) { await DisplayAlert("Error", ex.Message, "OK"); } finally { CircleOneTap.IsEnabled = true; } }
推荐方案
优先选择方案一,标志位机制能可靠拦截快速重复触发的事件,同时搭配页面关闭等待逻辑,确保导航状态正确重置。
内容的提问来源于stack exchange,提问作者Martin McDermot
相关产品推荐
相关产品推荐

