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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:57:19