NumberOfTapsRequired doesn't work for > 2

Viewed 2155

I have Xamarin Forms project and on my page there is this code:

<Image Source="genea_login_logo.png">
    <Image.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding LogoCommand}" NumberOfTapsRequired="2" />
    </Image.GestureRecognizers>
</Image>

It works as expected. However when I change NumberOfTapsRequired from 2 to 5, it doesn't work any more. Is this behaviour expected? Is it possible to implement 5-click command?

Edit: This is only on Android.

3 Answers

I amended Jesus' solution to also recognize single-tap events:

    public MyPage()
    {
        this.InitializeComponent();

        myControl.Tapped += async (sender, e) => 
        {
            await OnTappedAsync(sender, e);
        };

        ...
    }

    private DateTime? LastTap = null;
    private volatile byte NumberOfTaps = 0;  // volatile keyword necessary because of multi-threading
    private const int NumberOfTapsRequired = 2;
    private const int ToleranceInMs = 500;
    private async Task OnTappedAsync(object sender, EventArgs e)
    {
        if (LastTap == null || (DateTime.Now - LastTap.Value).TotalMilliseconds < ToleranceInMs)
        {
            if (NumberOfTaps == (NumberOfTapsRequired - 1))     // multi-tap?
            {
                NumberOfTaps = 0;
                LastTap = null;

                await App.Current.MainPage.DisplayAlert("Hi", "Double-tap hi from Gesture", "Ok");
                return;
            }
            else    // necessary number of taps not yet reached
            {
                NumberOfTaps++;
                LastTap = DateTime.Now;
            }
        }
        else
        {
            NumberOfTaps = 1;
            LastTap = DateTime.Now;
        }

        _ = Task.Factory.StartNew(async () =>
        {
            await Task.Delay(ToleranceInMs);    // check if there is still only one tap after latency
            if (NumberOfTaps == 1)
            {
                NumberOfTaps = 0;
                LastTap = null;
                Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
                {
                    await App.Current.MainPage.DisplayAlert("Hi", "Single-tap hi from Gesture", "Ok");
                });
            }
        });
    }
    long lastPress;
    private DateTime? LastTap = null;
    private int NumberOfTaps = 0;
    private const int NumberOfTapsRequired = 4;
    private const long ToleranceInMs = 1000;
    var logoTapRecognizer = new TapGestureRecognizer();
    logoTapRecognizer.Tapped += async(s, e) =>
    {
               long currentTime = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;
               if (currentTime - lastPress > ToleranceInMs)
               {
                    lastPress = currentTime;
                    NumberOfTaps = 1;
               }
               else
               {
                    NumberOfTaps++;
                    if(NumberOfTaps == NumberOfTapsRequired)
                          await App.Current.MainPage.DisplayAlert("Hi", "Hi from Gesture", "Ok");
               }
    };
    logo.GestureRecognizers.Add(logoTapRecognizer);
Related