зеркало из https://github.com/DeGsoft/maui-linux.git
[Android] Handle rapid taps when only single-tap recognizer is present (#1188)
* Handle rapid tapping correctly * Remove failed optimization attempt for 2-pointer gestures
This commit is contained in:
Родитель
40f574bc46
Коммит
adc5ff1eb9
|
@ -0,0 +1,92 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.Gestures)]
|
||||
#endif
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Bugzilla, 59863, "TapGestureRecognizer extremely finicky", PlatformAffected.Android)]
|
||||
public class Bugzilla59863_0 : TestContentPage
|
||||
{
|
||||
int _singleTaps;
|
||||
const string SingleTapBoxId = "singleTapView";
|
||||
|
||||
const string Singles = "singles(s)";
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
var instructions = new Label
|
||||
{
|
||||
Text = "Tap the box below several times quickly. "
|
||||
+ "The number displayed below should match the number of times you tap the box."
|
||||
};
|
||||
|
||||
var singleTapCounter = new Label {Text = $"{_singleTaps} {Singles}"};
|
||||
|
||||
var singleTapBox = new BoxView
|
||||
{
|
||||
WidthRequest = 100,
|
||||
HeightRequest = 100,
|
||||
BackgroundColor = Color.Bisque,
|
||||
AutomationId = SingleTapBoxId
|
||||
};
|
||||
|
||||
var singleTap = new TapGestureRecognizer
|
||||
{
|
||||
Command = new Command(() =>
|
||||
{
|
||||
_singleTaps = _singleTaps + 1;
|
||||
singleTapCounter.Text = $"{_singleTaps} {Singles} on {SingleTapBoxId}";
|
||||
})
|
||||
};
|
||||
|
||||
singleTapBox.GestureRecognizers.Add(singleTap);
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Margin = 40,
|
||||
HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill,
|
||||
Children = { instructions, singleTapBox, singleTapCounter }
|
||||
};
|
||||
}
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void TapsCountShouldMatch()
|
||||
{
|
||||
// Gonna add this test because we'd want to know if it _did_ start failing
|
||||
// But it doesn't really help much with this issue; UI test can't tap fast enough to demonstrate the
|
||||
// problem we're trying to solve
|
||||
|
||||
int tapsToTest = 5;
|
||||
|
||||
RunningApp.WaitForElement(SingleTapBoxId);
|
||||
|
||||
for (int n = 0; n < tapsToTest; n++)
|
||||
{
|
||||
RunningApp.Tap(SingleTapBoxId);
|
||||
}
|
||||
|
||||
RunningApp.WaitForElement($"{tapsToTest} {Singles} on {SingleTapBoxId}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoubleTapWithOnlySingleTapRecognizerShouldRegisterTwoTaps()
|
||||
{
|
||||
RunningApp.WaitForElement(SingleTapBoxId);
|
||||
RunningApp.DoubleTap(SingleTapBoxId);
|
||||
|
||||
RunningApp.WaitForElement($"2 {Singles} on {SingleTapBoxId}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.Gestures)]
|
||||
#endif
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Bugzilla, 59863, "TapGestureRecognizer extremely finicky", PlatformAffected.Android,
|
||||
issueTestNumber:1)]
|
||||
public class Bugzilla59863_1 : TestContentPage
|
||||
{
|
||||
int _doubleTaps;
|
||||
const string DoubleTapBoxId = "doubleTapView";
|
||||
|
||||
const string Doubles = "double(s)";
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
var instructions = new Label
|
||||
{
|
||||
Text = "Tap the box below once. The counter should not increment. "
|
||||
+ "Double tap the box. The counter should increment."
|
||||
};
|
||||
|
||||
var doubleTapCounter = new Label {Text = $"{_doubleTaps} {Doubles} on {DoubleTapBoxId}"};
|
||||
|
||||
var doubleTapBox = new BoxView
|
||||
{
|
||||
WidthRequest = 100,
|
||||
HeightRequest = 100,
|
||||
BackgroundColor = Color.Chocolate,
|
||||
AutomationId = DoubleTapBoxId
|
||||
};
|
||||
|
||||
var doubleTap = new TapGestureRecognizer
|
||||
{
|
||||
NumberOfTapsRequired = 2,
|
||||
Command = new Command(() =>
|
||||
{
|
||||
_doubleTaps = _doubleTaps + 1;
|
||||
doubleTapCounter.Text = $"{_doubleTaps} {Doubles} on {DoubleTapBoxId}";
|
||||
})
|
||||
};
|
||||
|
||||
doubleTapBox.GestureRecognizers.Add(doubleTap);
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Margin = 40,
|
||||
HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill,
|
||||
Children = { instructions, doubleTapBox, doubleTapCounter }
|
||||
};
|
||||
}
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void SingleTapWithOnlyDoubleTapRecognizerShouldRegisterNothing()
|
||||
{
|
||||
RunningApp.WaitForElement(DoubleTapBoxId);
|
||||
RunningApp.Tap(DoubleTapBoxId);
|
||||
|
||||
RunningApp.WaitForElement($"0 {Doubles} on {DoubleTapBoxId}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoubleTapWithOnlyDoubleTapRecognizerShouldRegisterOneDoubleTap()
|
||||
{
|
||||
RunningApp.WaitForElement(DoubleTapBoxId);
|
||||
RunningApp.DoubleTap(DoubleTapBoxId);
|
||||
|
||||
RunningApp.WaitForElement($"1 {Doubles} on {DoubleTapBoxId}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
#if UITEST
|
||||
[Category(UITestCategories.Gestures)]
|
||||
#endif
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Bugzilla, 59863, "TapGestureRecognizer extremely finicky", PlatformAffected.Android,
|
||||
issueTestNumber: 2)]
|
||||
public class Bugzilla59863_2 : TestContentPage
|
||||
{
|
||||
int _mixedSingleTaps;
|
||||
int _mixedDoubleTaps;
|
||||
const string MixedTapBoxId = "mixedTapView";
|
||||
|
||||
const string Singles = "singles(s)";
|
||||
const string Doubles = "double(s)";
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
var instructions = new Label
|
||||
{
|
||||
Text = "Tap the box below once. The single tap counter should increment. "
|
||||
+ "Double tap the box. The double tap counter should increment, "
|
||||
+ "but the single tap counter should not."
|
||||
};
|
||||
|
||||
var mixedSingleTapCounter = new Label {Text = $"{_mixedSingleTaps} {Singles}"};
|
||||
var mixedDoubleTapCounter = new Label {Text = $"{_mixedDoubleTaps} {Doubles}"};
|
||||
|
||||
var mixedTapBox = new BoxView
|
||||
{
|
||||
WidthRequest = 100,
|
||||
HeightRequest = 100,
|
||||
BackgroundColor = Color.Coral,
|
||||
AutomationId = MixedTapBoxId
|
||||
};
|
||||
|
||||
var mixedDoubleTap = new TapGestureRecognizer
|
||||
{
|
||||
NumberOfTapsRequired = 2,
|
||||
Command = new Command(() =>
|
||||
{
|
||||
_mixedDoubleTaps = _mixedDoubleTaps + 1;
|
||||
mixedDoubleTapCounter.Text = $"{_mixedDoubleTaps} {Doubles} on {MixedTapBoxId}";
|
||||
})
|
||||
};
|
||||
|
||||
var mixedSingleTap = new TapGestureRecognizer
|
||||
{
|
||||
NumberOfTapsRequired = 1,
|
||||
Command = new Command(() =>
|
||||
{
|
||||
_mixedSingleTaps = _mixedSingleTaps + 1;
|
||||
mixedSingleTapCounter.Text = $"{_mixedSingleTaps} {Singles} on {MixedTapBoxId}";
|
||||
})
|
||||
};
|
||||
|
||||
mixedTapBox.GestureRecognizers.Add(mixedDoubleTap);
|
||||
mixedTapBox.GestureRecognizers.Add(mixedSingleTap);
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Margin = 40,
|
||||
HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill,
|
||||
Children = { instructions, mixedTapBox, mixedSingleTapCounter, mixedDoubleTapCounter }
|
||||
};
|
||||
}
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void DoubleTapWithMixedRecognizersShouldRegisterDoubleTap()
|
||||
{
|
||||
RunningApp.WaitForElement(MixedTapBoxId);
|
||||
RunningApp.DoubleTap(MixedTapBoxId);
|
||||
|
||||
RunningApp.WaitForElement($"1 {Doubles} on {MixedTapBoxId}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SingleTapWithMixedRecognizersShouldRegisterSingleTap()
|
||||
{
|
||||
RunningApp.WaitForElement(MixedTapBoxId);
|
||||
RunningApp.Tap(MixedTapBoxId);
|
||||
|
||||
RunningApp.WaitForElement($"1 {Singles} on {MixedTapBoxId}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -218,6 +218,12 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla57910.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla58406.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla58833.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla51427.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59248.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59580.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59863_0.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59863_1.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59863_2.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ButtonBackgroundColorTest.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)CarouselAsync.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla34561.cs" />
|
||||
|
|
|
@ -61,7 +61,20 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (_disposed)
|
||||
return false;
|
||||
|
||||
return _tapDelegate(2);
|
||||
if (HasDoubleTapHandler())
|
||||
{
|
||||
return _tapDelegate(2);
|
||||
}
|
||||
|
||||
if (HasSingleTapHandler())
|
||||
{
|
||||
// If we're registering double taps and we don't actually have a double-tap handler,
|
||||
// but we _do_ have a single-tap handler, then we're really just seeing two singles in a row
|
||||
// Fire off the delegate for the second single-tap (OnSingleTapUp already did the first one)
|
||||
return _tapDelegate(1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GestureDetector.IOnDoubleTapListener.OnDoubleTapEvent(MotionEvent e)
|
||||
|
@ -134,7 +147,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
if (!HasDoubleTapHandler())
|
||||
{
|
||||
// We're not worried about double-tap, so OnSingleTap has already run the delegate
|
||||
// We're not worried about double-tap, so OnSingleTapUp has already run the delegate
|
||||
// there's nothing for us to do here
|
||||
return false;
|
||||
}
|
||||
|
@ -201,5 +214,12 @@ namespace Xamarin.Forms.Platform.Android
|
|||
return false;
|
||||
return _tapGestureRecognizers(2).Any();
|
||||
}
|
||||
|
||||
bool HasSingleTapHandler()
|
||||
{
|
||||
if (_tapGestureRecognizers == null)
|
||||
return false;
|
||||
return _tapGestureRecognizers(1).Any();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче