Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,26 @@ public bool OnTouchEvent(MotionEvent e)
}

var eventConsumed = false;

bool hasOnlyPointer =
!ViewHasPinchGestures() &&
!ViewHasNonPointerTouchGestures();

if (ViewHasPinchGestures())
{
eventConsumed = _scaleDetector.Value.OnTouchEvent(e);
}

if (!ViewHasPinchGestures() || !_scaleDetector.Value.IsInProgress)
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
eventConsumed = _tapAndPanAndSwipeDetector.Value.OnTouchEvent(e) || eventConsumed;
{
var detectorHandled = _tapAndPanAndSwipeDetector?.Value.OnTouchEvent(e) ?? false;
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated

// If only pointer gestures → do not consume the event
if (hasOnlyPointer)
eventConsumed = false;
else
eventConsumed = detectorHandled || eventConsumed;
}

return eventConsumed;
}
Expand Down Expand Up @@ -406,5 +419,23 @@ void UpdateIsEnabled()

_isEnabled = Element.IsEnabled;
}

bool ViewHasNonPointerTouchGestures()
{
if (View is null)
return false;

var recognizers = View.GetCompositeGestureRecognizers();
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
if (recognizers is null || recognizers.Count == 0)
return false;

foreach (var recognizer in recognizers)
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
{
if (recognizer is not PointerGestureRecognizer)
return true;
}

return false;
}
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
}
}
63 changes: 63 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue34491.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 34491, "CollectionView item selection not triggered when PointerGestureRecognizer is added inside ItemTemplate", PlatformAffected.Android)]
public class Issue34491 : ContentPage
{
public Issue34491()
{
var statusLabel = new Label
{
Text = "No Selection",
AutomationId = "StatusLabel",
Padding = new Thickness(10),
FontSize = 18
};

var collectionView = new CollectionView
{
AutomationId = "TestCollectionView",
SelectionMode = SelectionMode.Single,
ItemsSource = new List<string> { "Item 1", "Item 2", "Item 3" },
ItemTemplate = new DataTemplate(() =>
{
var label = new Label
{
Padding = new Thickness(10),
FontSize = 16
};
label.SetBinding(Label.TextProperty, ".");
label.SetBinding(Label.AutomationIdProperty, ".");

var grid = new Grid
{
BackgroundColor = Colors.LightGray,
Padding = new Thickness(10),
HeightRequest = 50,
Children = { label }
};

var pointerGesture = new PointerGestureRecognizer();
pointerGesture.PointerEntered += (s, e) => { };
pointerGesture.PointerExited += (s, e) => { };
grid.GestureRecognizers.Add(pointerGesture);

return grid;
})
};

collectionView.SelectionChanged += (s, e) =>
{
if (e.CurrentSelection.Count > 0)
{
statusLabel.Text = $"Selected: {e.CurrentSelection[0]}";
}
};

Content = new VerticalStackLayout
{
Padding = new Thickness(10),
Spacing = 10,
Children = { statusLabel, collectionView }
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#if ANDROID
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue34491 : _IssuesUITest
{
public Issue34491(TestDevice device) : base(device) { }

public override string Issue => "CollectionView item selection not triggered when PointerGestureRecognizer is added inside ItemTemplate";

[Test]
[Category(UITestCategories.CollectionView)]
public void CollectionViewSelectionWorksWithPointerGestureRecognizer()
{
// Wait for CollectionView
App.WaitForElement("TestCollectionView");

// Ensure StatusLabel exists
App.WaitForElement("StatusLabel");

var initialText = App.FindElement("StatusLabel").GetText() ?? string.Empty;
Assert.That(initialText, Is.EqualTo("No Selection"));

// Tap item
App.WaitForElement("Item 1");
App.Tap("Item 1");

// Retry loop for UI update
string finalText = string.Empty;

for (int i = 0; i < 10; i++)
{
finalText = App.FindElement("StatusLabel").GetText() ?? string.Empty;

if (finalText == "Selected: Item 1")
break;

Thread.Sleep(500);
}
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated

Assert.That(finalText, Is.EqualTo("Selected: Item 1"),
"SelectionChanged should fire when tapping a CollectionView item that has a PointerGestureRecognizer");
}
}
#endif
Comment thread
jpd21122012 marked this conversation as resolved.
Outdated
Loading