Bug 59961 - TapGestureRecognizer with NumberOfTapsRequired="1" works only with double tap
Summary: TapGestureRecognizer with NumberOfTapsRequired="1" works only with double tap
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Android (show other bugs)
Version: 2.4.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: E.Z. Hart [MSFT]
URL:
: 59873 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-10-04 14:50 UTC by VAGGELIS KARADIMOS
Modified: 2017-10-23 17:14 UTC (History)
9 users (show)

See Also:
Tags: fr
Is this bug a regression?: Yes
Last known good build:


Attachments
Reproduction attempt (296.31 KB, application/x-zip-compressed)
2017-10-04 20:55 UTC, E.Z. Hart [MSFT]
Details

Description VAGGELIS KARADIMOS 2017-10-04 14:50:03 UTC
With  Xamarin.Forms 2.4.0.282 and 2.4.0.800 the following xaml section fires the tap event 
only with double click on the image.

With version 2.3.4.270 works fine with single tap.

========================================================================================= 

  <StackLayout  HorizontalOptions="FillAndExpand">
                    <Image x:Name="paybuybutt" Aspect="AspectFit" Source="{local:ImageResource           iBankPaySpot.Images.Buttons.mnupaybuy.png}">
                      <Image.GestureRecognizers>
                          <TapGestureRecognizer  Tapped="OnRightTapped" NumberOfTapsRequired="1"/>
                      </Image.GestureRecognizers>
                    </Image>
                 </StackLayout>
Comment 1 VAGGELIS KARADIMOS 2017-10-04 14:51:00 UTC
correction on versio 2.4.0.280
Comment 2 Paul DiPietro [MSFT] 2017-10-04 14:57:37 UTC
Duplicating 25943 as we have reported Tap Gesture issues.

*** This bug has been marked as a duplicate of bug 25943 ***
Comment 3 E.Z. Hart [MSFT] 2017-10-04 20:55:17 UTC
Created attachment 25114 [details]
Reproduction attempt

Vaggelis,

I'm attempting to reproduce the problem and so far I have not been able to. I've attached my reproduction project - it uses an image, a tap gesture with NumberOfTapsRequired set to 1, and Xamarin Forms version 2.4.0.280. Could you let me know if you see the same problem with this project? If not, is there a detail I'm missing to recreate this problem?
Comment 4 VAGGELIS KARADIMOS 2017-10-05 18:39:24 UTC
Hi,

I have the same strange behavior also with your project.
see debugger output window.

=========================================
[ViewRootImpl@9a599e7[Image Tapped]] mHardwareRenderer.initialize() mSurface={isValid=true -803211264} hwInitialized=true
[mali_winsys] EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000,  [1592x856]-format:1
[ViewRootImpl@9a599e7[Image Tapped]] MSG_WINDOW_FOCUS_CHANGED 1
[ViewRootImpl@9a599e7[Image Tapped]] mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -803211264}
[ViewRootImpl@9a599e7[Image Tapped]] MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
[ViewRootImpl@2d4436e[MainActivity]] MSG_WINDOW_FOCUS_CHANGED 0
[ViewRootImpl@9a599e7[Image Tapped]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@9a599e7[Image Tapped]] ViewPostImeInputStage processPointer 1
[OpenGLRenderer] endAllActiveAnimators on 0xcc009900 (RippleDrawable) with handle 0xcf8597e0
[ViewRootImpl@9a599e7[Image Tapped]] mHardwareRenderer.destroy()#4
[ViewRootImpl@9a599e7[Image Tapped]] dispatchDetachedFromWindow
[InputTransport] Input channel destroyed: fd=73
[ViewRootImpl@2d4436e[MainActivity]] MSG_WINDOW_FOCUS_CHANGED 1
[ViewRootImpl@2d4436e[MainActivity]] mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -797829120}
[ViewRootImpl] sendUserActionEvent() mView == null
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
Thread finished: <Thread Pool> #3
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
Thread finished: <Thread Pool> #5
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 0
[ViewRootImpl@2d4436e[MainActivity]] ViewPostImeInputStage processPointer 1
[ViewRootImpl@d21b506[Image Tapped]] ThreadedRenderer.create() translucent=true
[InputTransport] Input channel constructed: fd=73
[ViewRootImpl@d21b506[Image Tapped]] setView = DecorView@52617c7[Image Tapped] touchMode=true
[ViewRootImpl@d21b506[Image Tapped]] dispatchAttachedToWindow
[ViewRootImpl@d21b506[Image Tapped]] Relayout returned: oldFrame=[0,0][0,0] newFrame=[36,1006][1404,1638] result=0x27 surface={isValid=true -802807808} surfaceGenerationChanged=true
[ViewRootImpl@d21b506[Image Tapped]] mHardwareRenderer.initialize() mSurface={isValid=true -802807808} hwInitialized=true
[mali_winsys] EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000,  [1592x856]-format:1
[ViewRootImpl@d21b506[Image Tapped]] MSG_WINDOW_FOCUS_CHANGED 1
[ViewRootImpl@d21b506[Image Tapped]] mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -802807808}
[ViewRootImpl@d21b506[Image Tapped]] MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
[ViewRootImpl@2d4436e[MainActivity]] MSG_WINDOW_FOCUS_CHANGED 0
Comment 5 E.Z. Hart [MSFT] 2017-10-06 16:32:42 UTC
*** Bug 59873 has been marked as a duplicate of this bug. ***
Comment 6 Cameron 2017-10-06 18:13:12 UTC
In reply to E.Z. Hard

To give you more detail too. My Frame that I have been trying to attach GR events has content set to a StackLayout. Here is my control class to help you out:

public class ButtonIcon : Frame
	{
		public ButtonIcon(string text, Color backColor = default(Color), Color textColor = default(Color), double? fontSize = null, FontAttributes fontAttributes = FontAttributes.None, string icon = null, string commandParameterBinding = null, bool isVisibleBinding = true, bool addShadow = false)
		{
			if (backColor == default(Color))
				backColor = Colors.DefaultButton;

			if (textColor == default(Color))
				textColor = Colors.DefaultButtonText;

			var iconImage = new IconImage
			{
				IconSize = fontSize ?? FontSizes.LabelL,
				IconColor = textColor,
				Icon = icon,
				HorizontalOptions = LayoutOptions.Start
			};

			var buttonLabel = new Label
			{
				Text = text,
				FontSize = fontSize ?? FontSizes.LabelL,
				TextColor = textColor,
				VerticalOptions = LayoutOptions.Center,
				HorizontalTextAlignment = TextAlignment.Center,
				InputTransparent = true
			};

			var container = new StackLayout
			{
				Orientation = StackOrientation.Horizontal,
				HorizontalOptions = LayoutOptions.Center
			};

			IsVisible = isVisibleBinding;
			HasShadow = addShadow;
			HorizontalOptions = LayoutOptions.FillAndExpand;
			BackgroundColor = backColor;
			Padding = new Thickness(10, 15);

			if (icon != null)
				container.Children.Add(iconImage);

			container.Children.Add(buttonLabel);
			Content = container;
		}
	}
Comment 7 Cameron 2017-10-06 18:34:28 UTC
In reply to comment #6

Also IconImage is the FormsPlugin.Iconize plugin.

Thanks
Comment 8 Cameron 2017-10-06 18:41:35 UTC
I actually think I found out what my issue is. In some of my layouts the Content Page Content is set to a grid. If I change it to a stack layout instead then my TapGestureRecognizers work just fine. Thoughts?
Comment 9 cunnpole 2017-10-08 21:38:52 UTC
Are you consistently seeing it requiring a double tap or is it sometimes more (or less). The issue I see is more like comment 29 here: https://bugzilla.xamarin.com/show_bug.cgi?id=25943#c29

Sometimes it works with 1 if I very carefully tap the screen without any movement in x or y. It often takes 2 taps, although sometimes take up to 5 or 6.

I've always been a bit suspicious of xamarin app taps on android, but this latest release is very poor. 

It happens in the 3 projects I've tested with a variety of layouts. I can also reproduce with my touchscreen on a dev machine. It always works perfectly with the mouse so it is just an issue with taps. On my Sony Z5 single taps don't work at all. It takes 2 or more taps for every GR in the whole app.
Comment 10 cunnpole 2017-10-09 09:32:06 UTC
I've set up a test rig with a stylus, a large button and a counter. On a Samsung Tab A I get a 100% hit rate. On a Sony Z5 I get 74% hit rate. On a Dev laptop with a touchscreen I get similar results. On an HTC One (Android 4.4) I get an 82% hit rate. This is with little or no X or Y movement. 

Things get significantly worse when I just use my fingers to do the taps in a likely usage scenario. Tab A drops to 90%. Z5 drops to 40% and HTC One to 64%. 

If I use Mr Gestures plugin then I always get 98-100% in either scenario. 

I have the tap GR on a frame containing an image and 2 labels. This Frame is in a H StackLayout, V Stacklayout in a ScrollView.

When the failures occur they often happen in bursts, so I can get 3 in a row that work then 5 that fail. Weirdly it seems to be worse in portrait mode on phones.
Comment 11 E.Z. Hart [MSFT] 2017-10-09 16:18:34 UTC
PR: https://github.com/xamarin/Xamarin.Forms/pull/1188
Comment 12 Alexander Melchers 2017-10-16 10:37:09 UTC
I seem to be running into similar issues with the tap gesture recognizer on Android not firing consistently. This might also be the cause for double-tapping working, as I myself have observed that the second tap frequently DOES fire, even if not entirely consistently either.

Handling raw touch events (through a renderer) does not suffer from the above problems, however.

The issue also does not occur on Xamarin.Forms version 2.3.4.270, only the versions above, as has been stated.
Comment 13 Rui Marinho 2017-10-16 14:31:02 UTC
Should be fixed in 2.4.0 service release 2
Comment 14 Alexander Melchers 2017-10-16 14:40:25 UTC
Hi Rui,

Any indication of when we may expect this version of Xamarin.Forms, as we won't be able to update XF until then...

All the best,
Alexander.
Comment 15 David Ortinau [MSFT] 2017-10-23 15:16:08 UTC
Alexander, this service release is now published. Please update and confirm it fixes your issue. If not, please open a new issue with details specific to your case. We've found not all the tap issues being reported are the same, so please be specific.
Comment 16 Alexander Melchers 2017-10-23 17:14:48 UTC
Hi David,

The latest Xamarin.Forms release (2.4.0) seems to have indeed fixed the original issue I had with having to double (or multi-)tap images for the single-tap gesture recognizer to pick up on them. However, the new 2.4.0-version of Xamarin.Forms seems to have introduced another problem related to the Android GestureDetector, which I haven't fully investigated yet. However, when I do, I'll make sure to file a new bug report.

Thanks, and best regards,
Alexander.

Note You need to log in before you can comment on or make changes to this bug.