Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Android] TapGestureRecognizer do not fire the tapped event on "normal" tap/click. #1628

Open
mathias3d opened this issue Jan 21, 2018 · 13 comments
Labels
a/gestures 🖖 e/3 🕒 3 help wanted We welcome community contributions to any issue, but these might be a good place to start! m/high impact ⬛ p/Android proposal-accepted t/enhancement ➕ up-for-grabs We welcome community contributions to any issue, but these might be a good place to start!

Comments

@mathias3d
Copy link

mathias3d commented Jan 21, 2018

Bug report best practices: https://github.com/xamarin/Xamarin.Forms/wiki/Submitting-Issues

Description

On Android the TapGestureRecognizer do not fire the tapped event on "normal" tap/click.
The finger is always sliding a little over the screen when you are tapping it, the TapGestureRecognizer have a very small "sliding"-tolerance. This makes the TapGestureRecognizer to only fire a tapped event if you click much more carefully than on a normal button.

Steps to Reproduce

  1. Device: Samsung SM-T580 (Galaxy Tab A)
  2. OS: Android 7.0
  3. Enable developer options: Show Touches and Show Pointer location.

Create any basic Xamarin.Forms project and apply a TapGestureRecognizer to any basic element (Text, StackLayout etc.)

Expected Behavior

The tapped event should be fired even if a little sliding occurs, just like normal buttons do.

Actual Behavior

No event is fired when a little sliding occurs, like it does on buttons.

Basic Information

  • Version with issue: Xamarin.Forms 2.5.0.122203
  • Platform Target Frameworks:
    • Android: 7.0
  • Android Support Library Version: Xamarin.Android.Support.v4 (26.1.0.1), Xamarin.Android.Support.v7.AppCompat (26.1.0.1)
  • Affected Devices: Samsung SM-T580 (Galaxy Tab A)

Screenshots

Reproduction Link

@mathias3d
Copy link
Author

Related to this maybe?
#1374

@timahrentlov
Copy link

When will Xamarin Forms support the tap event on Android ? It's a pretty basic feature for a mobile development framework.

@kingces95 kingces95 self-assigned this Jul 6, 2018
@kingces95
Copy link
Contributor

App14.zip

Reproduction of the behavior which is as described.

A button will recognize any gesture as a click regardless of how much sliding occurs so long as the sliding starts and stops within the button.

A label with a tap gesture recognizer will register a tap with only a few pixels of sliding tolerance.

@kingces95
Copy link
Contributor

@jassmith says we should add a knob to allow users to control sliding tolerance for the tap gesture recognizer. I doubt we'll go as far as making the tap gesture recognizer logic match that of a button.

@mathias3d
Copy link
Author

I am glad to hear that this is being dealt with. A setting for the sliding tolerance would be appreciated, right now i am getting allot of complaints about people not being able to use our app because the users think they cant click on the items.

@samhouts samhouts added i/critical i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often m/high impact ⬛ e/7 🕖 7 and removed i/critical labels Jul 23, 2018
@PureWeen PureWeen assigned PureWeen and unassigned kingces95 Aug 9, 2018
@PureWeen PureWeen removed their assignment Oct 23, 2018
@samhouts samhouts added the inactive Issue is older than 6 months and needs to be retested label Jan 2, 2019
@mclillill
Copy link

@mathias3d which event fires instead of the tap? we have the same problem. I'd say it happens about every 5th time for me that the the tap is no firing.

@mclillill
Copy link

Possibly releated: #3173

@tompi
Copy link

tompi commented Sep 4, 2019

Also bitten by this. Getting complaints from users(only on android).

I will probably have to make my own "ButtonTapGestureRecognizer"(or perhaps "TapGestureRecognizerThatWorksAsExpectedOnAndroid")...

This definitely works different on ios and android, and should be considered a bug IMHO.

@tompi
Copy link

tompi commented Nov 8, 2019

I made this class to work around the problem:

public class MicroSwipeOrTapListener
{
        private readonly double _microSwipeMaxLength;
        public event EventHandler MicroSwipeOrTapHasHappened;
        private double _translatedX, _translatedY;

        public MicroSwipeOrTapListener(View view)
        {
            // If swipe was less than a 20th of the screen, we consider it a tap
            _microSwipeMaxLength = App.DisplayScreenWidth / 20d;
            // Only listen for micro swipes on android
            if (Device.RuntimePlatform == Device.Android)
            {
                var panRecognizer = new PanGestureRecognizer();
                panRecognizer.PanUpdated += OnPanUpdated;
                view.GestureRecognizers.Add(panRecognizer);
            }
            // Listen for taps on both platforms(on ios, this includes micro swipes)
            var tapRecognizer = new TapGestureRecognizer();
            tapRecognizer.Tapped += OnTapped;
            view.GestureRecognizers.Add(tapRecognizer);
        }

        private void OnTapped(object sender, EventArgs e)
        {
            MicroSwipeOrTapHasHappened?.Invoke(sender, e);
        }

        void OnPanUpdated(object sender, PanUpdatedEventArgs e)
        {
            switch (e.StatusType)
            {
                case GestureStatus.Running:
                    _translatedX = e.TotalX;
                    _translatedY = e.TotalY;
                    break;

                case GestureStatus.Completed:
                    // If all movements(regardless of direction) was less than treshold: fire microswipe event
                    if (Math.Max(Math.Abs(_translatedX), Math.Abs(_translatedY)) <= _microSwipeMaxLength)
                    {
                        MicroSwipeOrTapHasHappened?.Invoke(this, e);
                    }
                    break;
                case GestureStatus.Started:
                    break;
                case GestureStatus.Canceled:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }            
        }
}

@mclillill
Copy link

@samhouts You moved the issue to "Needs Specification". What exactly would you like to have specified?

@bcaceiro
Copy link

This is huge, since we use TapGestureRecognizer for all the events. With a small drag, the event will simply not fire.

Also, not sure if need to open a new issue but: Pressed and Released Events in TapGesture, is it possible?

@samhouts samhouts added a/gestures 🖖 proposal-accepted e/3 🕒 3 and removed inactive Issue is older than 6 months and needs to be retested e/7 🕖 7 labels Dec 31, 2019
@samhouts samhouts added help wanted We welcome community contributions to any issue, but these might be a good place to start! up-for-grabs We welcome community contributions to any issue, but these might be a good place to start! and removed i/high Completely doesn't work, crashes, or is unusably slow, has no obvious workaround; occurs less often labels Dec 31, 2019
@Zukka
Copy link

Zukka commented Jan 15, 2020

Any news about this?

@maexsp
Copy link
Contributor

maexsp commented Feb 19, 2020

Same issue here. TapGestureRecognizer is needed lots of time on customized pages. Just a little move during tap and the gesture is not fired! May you can provide a property " double TapSlideSensitivity" similar to NumberOfTapsRequired where it is possible to define how many x & y coordinates are tolerated between Down and Up event to fire a TapGesture finally.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a/gestures 🖖 e/3 🕒 3 help wanted We welcome community contributions to any issue, but these might be a good place to start! m/high impact ⬛ p/Android proposal-accepted t/enhancement ➕ up-for-grabs We welcome community contributions to any issue, but these might be a good place to start!
Projects
None yet
Development

No branches or pull requests