[Android] Fix: TapGestureRecognizer not firing on horizontal ScrollView - #35897
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35897Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35897" |
|
Hey there @@Shalini-Ashokan! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/review -b feature/enhanced-reviewer -p android |
247eb31 to
338584a
Compare
🔍 Skill Validation Results✅ Static Checks PassedSkills checked: 18 | Agents checked: 4 Full validator output⏭️ LLM Evaluation: Skipped
|
338584a to
4804f0f
Compare
|
/review -b feature/enhanced-reviewer -p android |
This comment has been minimized.
This comment has been minimized.
|
I think we don't have to wait till net11 to release this fix |
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@Shalini-Ashokan — new AI review results are available based on this last commit:
e43b78a. To request a fresh review after new comments or commits, comment/review rerun.
🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: ANDROID · Base: net11.0 · Merge base: 8ee100c5
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue28064 Issue28064 |
✅ FAIL — 698s | ✅ PASS — 1460s |
🔴 Without fix — 🖥️ Issue28064: FAIL ✅ · 698s
(truncated to last 15,000 chars)
ebug/net11.0-android37.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net11.0-android37.0/Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net11.0-android37.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net11.0-android37.0/Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Controls.TestCases.HostApp.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Core.HybridWebViewSourceGen -> /home/vsts/work/1/s/artifacts/bin/Core.HybridWebViewSourceGen/Debug/netstandard2.0/Microsoft.Maui.Core.HybridWebViewSourceGen.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Maps.dll
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Maps.dll
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Foldable.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:07:58.80
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Starting: Intent { act=android.settings.SETTINGS }
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Determining projects to restore...
Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 1.76 sec).
Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.39 sec).
Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 5 ms).
Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 1.87 sec).
Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 6.92 sec).
Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 4.69 sec).
Restored /home/vsts/work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 12 ms).
Restored /home/vsts/work/1/s/src/Controls/tests/TestCases.Android.Tests/Controls.TestCases.Android.Tests.csproj (in 4.29 sec).
6 of 14 projects are up-to-date for restore.
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net11.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net11.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net11.0/Controls.CustomAttributes.dll
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net11.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Core.HybridWebViewSourceGen -> /home/vsts/work/1/s/artifacts/bin/Core.HybridWebViewSourceGen/Debug/netstandard2.0/Microsoft.Maui.Core.HybridWebViewSourceGen.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net11.0/Microsoft.Maui.Controls.dll
UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net11.0/UITest.Core.dll
VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net11.0/UITest.Appium.dll
UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net11.0/UITest.NUnit.dll
VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v11.0)
A total of 1 test files matched the specified pattern.
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 06/26/2026 12:32:36 FixtureSetup for Issue28064(Android)
>>>>> 06/26/2026 12:32:53 The FixtureSetup threw an exception. Attempt 0/1.
Exception details: System.TimeoutException: TapGestureRecognizer on ScrollView background does not fire on Android
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 584
>>>>> 06/26/2026 12:32:56 FixtureSetup for Issue28064(Android)
>>>>> 06/26/2026 12:33:12 The FixtureSetup threw an exception. Attempt 1/1.
Exception details: System.TimeoutException: TapGestureRecognizer on ScrollView background does not fire on Android
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 584
>>>>> 06/26/2026 12:33:12 Log types: logcat, bugreport, server
>>>>> 06/26/2026 12:33:14 Log types: logcat, bugreport, server
Failed ScrollViewBackgroundTapGestureShouldFire [51 s]
Error Message:
OneTimeSetUp: System.TimeoutException : TapGestureRecognizer on ScrollView background does not fire on Android
Stack Trace:
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 584
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed ScrollViewChildTapGestureShouldFire [51 s]
Error Message:
OneTimeSetUp: System.TimeoutException : TapGestureRecognizer on ScrollView background does not fire on Android
Stack Trace:
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 584
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Setup failed for test fixture Microsoft.Maui.TestCases.Tests.Issues.Issue28064(Android)
System.TimeoutException : TapGestureRecognizer on ScrollView background does not fire on Android
StackTrace: at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 584
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 11.0.0-preview.6.26323.106)
[xUnit.net 00:00:00.13] Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.73] Discovered: Controls.TestCases.Android.Tests
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue28064.trx
Total tests: 2
Failed: 2
Total time: 1.1073 Minutes
Test Run Failed.
>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue28064.trx
🟢 With fix — 🖥️ Issue28064: PASS ✅ · 1460s
(truncated to last 15,000 chars)
d]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
Build FAILED.
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: Mono.AndroidTools.InstallFailedException: Unexpected install output: cmd: Failure calling service package: Broken pipe (32) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass102_0.<InstallPackage>b__0(Task`1 t) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: --- End of stack trace from previous location --- [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: --- End of stack trace from previous location --- [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at AndroidDeviceExtensions.PushAndInstallPackageAsync(AndroidDevice device, PushAndInstallCommand command, CancellationToken token) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.51/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
0 Warning(s)
1 Error(s)
Time Elapsed 00:13:51.84
* daemon not running; starting now at tcp:5037
* daemon started successfully
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net11.0-android37.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net11.0-android37.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net11.0-android37.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Core.HybridWebViewSourceGen -> /home/vsts/work/1/s/artifacts/bin/Core.HybridWebViewSourceGen/Debug/netstandard2.0/Microsoft.Maui.Core.HybridWebViewSourceGen.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net11.0-android37.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net11.0-android37.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net11.0-android37.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net11.0-android37.0/Microsoft.Maui.Controls.Foldable.dll
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net11.0-android37.0/Microsoft.Maui.Controls.Maps.dll
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net11.0-android37.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Controls.TestCases.HostApp.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Core.HybridWebViewSourceGen -> /home/vsts/work/1/s/artifacts/bin/Core.HybridWebViewSourceGen/Debug/netstandard2.0/Microsoft.Maui.Core.HybridWebViewSourceGen.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Foldable.dll
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Xaml.dll
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.Maui.Controls.Maps.dll
Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:07:58.89
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Starting: Intent { act=android.settings.SETTINGS }
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net11.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net11.0/Microsoft.Maui.Essentials.dll
Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net11.0/Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net11.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Core.HybridWebViewSourceGen -> /home/vsts/work/1/s/artifacts/bin/Core.HybridWebViewSourceGen/Debug/netstandard2.0/Microsoft.Maui.Core.HybridWebViewSourceGen.dll
##vso[build.updatebuildnumber]11.0.0-ci+azdo.14498334
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net11.0/Microsoft.Maui.Controls.dll
UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net11.0/UITest.Core.dll
UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net11.0/UITest.NUnit.dll
UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net11.0/UITest.Appium.dll
VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll (.NETCoreApp,Version=v11.0)
A total of 1 test files matched the specified pattern.
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net11.0/Controls.TestCases.Android.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 06/26/2026 12:57:33 FixtureSetup for Issue28064(Android)
>>>>> 06/26/2026 12:57:36 ScrollViewBackgroundTapGestureShouldFire Start
>>>>> 06/26/2026 12:57:39 ScrollViewBackgroundTapGestureShouldFire Stop
Passed ScrollViewBackgroundTapGestureShouldFire [3 s]
>>>>> 06/26/2026 12:57:39 ScrollViewChildTapGestureShouldFire Start
>>>>> 06/26/2026 12:57:40 ScrollViewChildTapGestureShouldFire Stop
Passed ScrollViewChildTapGestureShouldFire [698 ms]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 11.0.0-preview.6.26323.106)
[xUnit.net 00:00:00.14] Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.68] Discovered: Controls.TestCases.Android.Tests
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue28064.trx
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 23.4775 Seconds
>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue28064.trx
📁 Fix files reverted (2 files)
src/Core/src/Platform/Android/MauiScrollView.cssrc/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
📱 UI Tests — ScrollView,ViewBaseTests
Detected UI test categories: ScrollView,ViewBaseTests
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
ScrollView |
0/198 (setup failed; 198 marked failed) | — |
ViewBaseTests |
0/119 (setup failed; 119 marked failed) | — |
⚠️ ScrollView — fixture setup failed for 198 tests
NUnit reported a OneTimeSetUp/fixture setup failure before test bodies ran; the TRX marked each affected test failed.
Multiple setup failure signatures were present; showing the first one. See the TRX artifact for all details.
OneTimeSetUp: System.TimeoutException : Timed out waiting for Go To Test button to appear
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests.UtilExtensions.NavigateToGallery(IApp app, String page) in /_/src/Controls/tests/TestCases.Shared.Tests/UtilExtensions.cs:line 37
at Microsoft.Maui.TestCases.Tests._GalleryUITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_GalleryUITest.cs:line 57
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
⚠️ ViewBaseTests — fixture setup failed for 119 tests
NUnit reported a OneTimeSetUp/fixture setup failure before test bodies ran; the TRX marked each affected test failed.
Multiple setup failure signatures were present; showing the first one. See the TRX artifact for all details.
OneTimeSetUp: System.TimeoutException : Timed out waiting for Go To Test button to appear
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests.UtilExtensions.NavigateToGallery(IApp app, String page) in /_/src/Controls/tests/TestCases.Shared.Tests/UtilExtensions.cs:line 37
at Microsoft.Maui.TestCases.Tests._GalleryUITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_GalleryUITest.cs:line 57
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)
📋 Pre-Flight — Context & Validation
Issue: #28064 - ScrollView TapGestureRecognizer - taping background doesn't fire Tapped event
PR: #35897 - [Android] Fix: TapGestureRecognizer not firing on horizontal ScrollView
Platforms Affected: Android
Files Changed: 2 implementation, 2 test
Key Findings
- The issue is Android-only: a
TapGestureRecognizerattached to a horizontalScrollViewdoes not fire when tapping uncovered ScrollView background. - PR fix caches the parent
MauiScrollViewtouch listener via publicSetOnTouchListeneroverride, then invokes it from the nestedMauiHorizontalScrollView.OnTouchEvent. - Gate result supplied by caller: Gate ✅ PASSED — tests fail without fix and pass with PR fix. Gate was not re-run.
- Prior review surfaces contain earlier failed/needs-changes summaries; latest supplied gate supersedes prior gate failures, but code-review still found architectural concerns with the public listener hook.
Code Review Summary
Verdict: NEEDS_CHANGES
Confidence: low
Errors: 2 | Warnings: 1 | Suggestions: 0
Key code review findings:
- ❌
src/Core/src/Platform/Android/MauiScrollView.cs:38/src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt:335— publicSetOnTouchListeneroverride/PublicAPI entry is used as an internal MAUI gesture-forwarding hook. - ❌
src/Core/src/Platform/Android/MauiScrollView.cs:496—IOnTouchListener.OnTouchreturn value is ignored, which breaks normal Android listener consumption semantics if external listeners are involved. ⚠️ src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28064.cs:20—App.Tap("TheScrollView")may tap the element center rather than a guaranteed uncovered background point.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35897 | Cache parent IOnTouchListener by overriding public MauiScrollView.SetOnTouchListener; nested MauiHorizontalScrollView.OnTouchEvent invokes the cached listener. |
✅ PASSED (Gate) | MauiScrollView.cs, PublicAPI.Unshipped.txt, Issue28064 UI tests |
Original PR; behavior works but code review flags public API/contract concerns. |
🔬 Code Review — Deep Analysis
Code Review — PR #35897
Independent Assessment
What this changes: Android horizontal/bidirectional MauiScrollView now caches the parent view’s touch listener and manually invokes it from MauiHorizontalScrollView.OnTouchEvent, plus UI tests for #28064.
Inferred motivation: Horizontal ScrollView wraps content in an inner HorizontalScrollView, so taps not claimed by children never reach MAUI’s gesture listener on the parent.
Reconciliation with PR Narrative
Author claims: The fix forwards only unclaimed horizontal-scroll touches to mirror vertical ScrollView gesture behavior.
Agreement/disagreement: The root cause matches the code. I disagree that using the public SetOnTouchListener override is the right hook; it exposes an internal gesture-forwarding mechanism and does not preserve Android listener semantics.
Prior Review Reconciliation
| Prior ❌ Error Finding | Source | Status | Evidence |
|---|---|---|---|
Public API/architectural concern: SetOnTouchListener override cements an internal hook as public API |
MauiBot [major] |
❌ Unresolved | Current diff still adds MauiScrollView.SetOnTouchListener at src/Core/src/Platform/Android/MauiScrollView.cs:38 and PublicAPI entry at PublicAPI.Unshipped.txt:335. |
Ignored IOnTouchListener.OnTouch return value breaks SetOnTouchListener contract |
MauiBot [major] |
❌ Unresolved | Current code still calls _touchListener?.OnTouch(...) and ignores the bool at MauiScrollView.cs:496. |
Blast Radius Assessment
- Runs for all instances: No, only Android
MauiScrollViewin horizontal/both orientation, but affects all horizontal ScrollViews with gestures. - Startup impact: No.
- Static/shared state: No.
CI Status
- Required-check result: undetermined —
gh pr checks --requiredfailed becauseghis unauthenticated. - Classification: undetermined; public check-runs show
maui-pr/Build Analysis failures, but full AzDO classification was unavailable. - Action taken: invoked
azdo-build-investigator; confidence capped low.
Findings
❌ Error — Public listener contract is used as an internal gesture hook
src/Core/src/Platform/Android/MauiScrollView.cs:38 / src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt:335
This adds a public override/PublicAPI entry only so MAUI can cache its own gesture listener. Since MauiScrollView is public, external callers now observe this forwarding behavior too. Prefer an internal MAUI-only hook/delegate set by GesturePlatformManager.
❌ Error — Consuming touch listeners are ignored
src/Core/src/Platform/Android/MauiScrollView.cs:496
IOnTouchListener.OnTouch returns true to consume the event. The current code ignores that and still forwards to parent/base scroll handling, so a consuming listener can fire while native scrolling proceeds. If scrolling must coexist for MAUI gestures, that is another reason to avoid reusing the public listener contract.
⚠️ Warning — Test may not prove the uncovered-background path
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28064.cs:20
App.Tap("TheScrollView") taps the element center, which may land over Child2Label rather than the brown uncovered area. Use GetRect() + coordinate tap in guaranteed empty background space, or size the layout to make the center an explicit background point.
Failure-Mode Probing
- External consuming listener returns
true: current code still scrolls/continues, unlike AndroidSetOnTouchListener. - Handler disconnect/reconnect: no static state, but cached listener correctness depends on Touch unsubscribe behavior.
- Child tap recognizer claims event: parent forwarding does not run, which matches intended child behavior.
Verdict: NEEDS_CHANGES
Confidence: low
Summary: The bug is real, but the fix should not expose/repurpose public SetOnTouchListener semantics for MAUI’s internal gesture forwarding. CI status is also undetermined/red from available public signals, so this cannot be LGTM.
🛠️ Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix-1 (claude-opus-4.6) |
Add an internal MauiScrollView.GestureTouchHandler callback set/cleared by GesturePlatformManager; MauiHorizontalScrollView.OnTouchEvent forwards unclaimed touches through that callback. |
✅ PASS | 2 files | Avoids new public API and avoids overriding/repurposing Android SetOnTouchListener; self-review clean. |
| PR | PR #35897 | Override public MauiScrollView.SetOnTouchListener, cache the listener, and invoke it from the inner horizontal scroll view. |
✅ PASSED (Gate) | 4 files | Original PR works behaviorally but adds a public API entry and ignores IOnTouchListener.OnTouch consumption semantics. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| n/a | n/a | Not run | Stop condition met after candidate 1: candidate passed all targeted tests and is demonstrably better than the PR fix because it avoids public API surface and preserves Android listener contract boundaries. |
Exhausted: No
Selected Fix: Candidate #1 — It passed the Android Issue28064 UI tests, avoids the PR's public SetOnTouchListener override/PublicAPI change, keeps the gesture-forwarding hook internal to MAUI, and has symmetric setup/teardown in GesturePlatformManager.
📝 Recommended PR Title & Description
Assessment: ✏️ Recommend updating — the current description accurately explains the submitted PR fix, but the winning candidate is try-fix-1, which uses an internal GestureTouchHandler instead of overriding SetOnTouchListener and adding public API.
Recommended title
[Android] ScrollView: Fire TapGestureRecognizer for horizontal background taps
Recommended description
### Issue Details
TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event.
### Root Cause
For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView. The horizontal child receives unclaimed background touch events, so Android does not run the parent MauiScrollView touch event path where GesturePlatformManager processes gesture recognizers.
### Description of Change
Add an internal MauiScrollView.GestureTouchHandler callback that GesturePlatformManager sets when subscribing gestures on a MauiScrollView and clears during resubscription/disposal. MauiHorizontalScrollView.OnTouchEvent invokes that internal callback for unclaimed horizontal/both ScrollView touch events so TapGestureRecognizer on the ScrollView background fires consistently with vertical ScrollView behavior.
This keeps the forwarding mechanism internal to MAUI gesture plumbing and avoids overriding the public Android SetOnTouchListener contract or adding a PublicAPI entry for an implementation detail.
### Issues Fixed
Fixes #28064
### Platforms Tested
- [x] Android
🏁 Report — Final Recommendation
Comparative Candidate Report — PR #35897
Summary
Winner: try-fix-1
All evaluated candidates address the Android horizontal ScrollView background-tap failure. No candidate in the available STEP 5a artifacts failed regression tests; the raw PR fix and try-fix-1 both have passing targeted results, while pr-plus-reviewer was evaluated as a sandbox refinement of the PR fix and was not separately re-run.
Candidate ranking
| Rank | Candidate | Regression result | Assessment |
|---|---|---|---|
| 1 | try-fix-1 |
PASS | Best overall. Uses an internal MauiScrollView.GestureTouchHandler callback set and cleared by GesturePlatformManager, avoids new public API, avoids repurposing SetOnTouchListener, and includes lifecycle cleanup. |
| 2 | pr-plus-reviewer |
Not re-run; expected pass | Improves the PR by honoring IOnTouchListener.OnTouch(...) consumption semantics, but still exposes an internal gesture-forwarding mechanism through public SetOnTouchListener/PublicAPI surface. |
| 3 | pr |
PASS | Fixes the reported behavior, but ignores the forwarded listener's return value and adds a public override/PublicAPI entry for an internal hook. |
Detailed comparison
pr
The submitted PR caches the parent MauiScrollView touch listener via SetOnTouchListener and invokes it from MauiHorizontalScrollView.OnTouchEvent.
Strengths:
- Passes the supplied gate: tests fail without the fix and pass with the fix.
- Correctly identifies the root cause: horizontal/both
ScrollViewuses a nestedMauiHorizontalScrollView, so parent touch listeners do not run for unclaimed background taps.
Concerns:
MauiScrollView.SetOnTouchListeneris public API, so this internal gesture-forwarding hook becomes observable API surface.- The return value from
IOnTouchListener.OnTouch(...)is ignored, so a consuming listener does not stop horizontal scroll handling the way Android dispatch normally would.
pr-plus-reviewer
This candidate applies the expert reviewer's actionable feedback to the PR by returning immediately when the cached listener consumes the event.
Strengths:
- Fixes the expert inline finding.
- Better matches Android
IOnTouchListenerconsumption semantics than the raw PR. - Likely preserves the targeted tap behavior because the gesture listener is still invoked from the horizontal child.
Concerns:
- Still retains the avoidable public
SetOnTouchListeneroverride and PublicAPI entry. - Not independently regression-tested in this phase.
try-fix-1
This STEP 5a candidate adds an internal Func<MotionEvent, bool>? GestureTouchHandler on MauiScrollView. GesturePlatformManager sets it when subscribing gestures on a MauiScrollView and clears it during resubscription/disposal; MauiHorizontalScrollView invokes it for unclaimed horizontal touches.
Strengths:
- PASS result in STEP 5a for both targeted UI tests:
ScrollViewBackgroundTapGestureShouldFireScrollViewChildTapGestureShouldFire
- Avoids any new public API and therefore avoids a
PublicAPI.Unshipped.txtentry. - Keeps the hook scoped to MAUI gesture plumbing instead of changing the public Android listener contract.
- Includes symmetric setup/teardown in
GesturePlatformManager.
Concerns:
- The STEP 5a diff currently invokes
GestureTouchHandler?.Invoke(ev)without acting on the bool result. This is less concerning than the PR's public-listener issue because the callback is internal MAUI plumbing, but the implementation can still be trivially tightened by honoring the return value if desired.
Decision
try-fix-1 wins because it passes the targeted regression tests and solves the root cause without adding public API or changing external SetOnTouchListener semantics. Candidates with failing regression tests would be ranked below passing candidates; none of the available candidates were recorded as failed.
🧭 Next Steps — alternative fix proposed (try-fix-1)
Automated review — alternative fix proposed
The expert-reviewer evaluation compared the PR fix against automatically generated candidates and selected try-fix-1 as the strongest fix.
Why: try-fix-1 won because it passed the targeted Android regression tests while avoiding the PR's public SetOnTouchListener/PublicAPI hook. It keeps the forwarding mechanism internal to MAUI gesture plumbing and includes lifecycle cleanup in GesturePlatformManager.
Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.
Candidate diff (try-fix-1)
diff --git a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs
index 83df87c830..f96fa5d4cb 100644
--- a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs
+++ b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs
@@ -10,6 +10,7 @@ using AndroidX.Core.View;
using AndroidX.RecyclerView.Widget;
using Microsoft.Maui.Controls.Internals;
using Microsoft.Maui.Graphics;
+using Microsoft.Maui.Platform;
using static Android.Views.View;
using AView = Android.Views.View;
@@ -223,6 +224,12 @@ namespace Microsoft.Maui.Controls.Platform
platformView.Touch -= OnPlatformViewTouched;
platformView.KeyPress -= OnKeyPress;
+ // Clear gesture touch handler for MauiScrollView horizontal child forwarding
+ if (platformView is MauiScrollView mauiScrollView)
+ {
+ mauiScrollView.GestureTouchHandler = null;
+ }
+
if (shouldAddTouchEvent)
{
@@ -240,6 +247,15 @@ namespace Microsoft.Maui.Controls.Platform
else
{
platformView.Touch += OnPlatformViewTouched;
+
+ // For MauiScrollView with horizontal/both orientation, the inner
+ // MauiHorizontalScrollView consumes touch events before the parent's
+ // Touch listener fires. Set a callback so the child can forward
+ // unclaimed events directly to the gesture system.
+ if (platformView is MauiScrollView scrollView)
+ {
+ scrollView.GestureTouchHandler = OnTouchEvent;
+ }
}
// If we have a TapGestureRecognizer or LongPressGestureRecognizer, we need to handle key presses
@@ -318,6 +334,11 @@ namespace Microsoft.Maui.Controls.Platform
ClearRecyclerViewTouchListener(platformView);
platformView.Touch -= OnPlatformViewTouched;
platformView.KeyPress -= OnKeyPress;
+
+ if (platformView is MauiScrollView scrollView)
+ {
+ scrollView.GestureTouchHandler = null;
+ }
}
_handler = null;
diff --git a/src/Core/src/Platform/Android/MauiScrollView.cs b/src/Core/src/Platform/Android/MauiScrollView.cs
index bc92251800..3127272904 100644
--- a/src/Core/src/Platform/Android/MauiScrollView.cs
+++ b/src/Core/src/Platform/Android/MauiScrollView.cs
@@ -32,6 +32,10 @@ namespace Microsoft.Maui.Platform
internal bool ShouldSkipOnTouch;
internal int HorizontalScrollOffset => _hScrollView?.ScrollX ?? 0;
+ // Invoked by MauiHorizontalScrollView to forward unclaimed touch events to the gesture system.
+ // Set by GesturePlatformManager when subscribing to gestures on this view.
+ internal Func<MotionEvent, bool>? GestureTouchHandler;
+
public MauiScrollView(Context context) : base(context)
{
_context = context;
@@ -480,6 +484,11 @@ namespace Microsoft.Maui.Platform
if (!_parentScrollView.Enabled)
return false;
+ // OnTouchEvent is only called when no child has claimed the touch event.
+ // Forward to the parent's gesture handler so TapGestureRecognizers on a
+ // horizontal/both ScrollView fire correctly.
+ _parentScrollView.GestureTouchHandler?.Invoke(ev);
+
// If the touch is caught by the horizontal scrollview, forward it to the parent
_parentScrollView.ShouldSkipOnTouch = true;
_parentScrollView.OnTouchEvent(ev);
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
Tests Failure Analysis
Test Failure Review: Not ready - click to expandOverall verdict: Not ready 10 failures are deterministically regressed vs the base branch (green on base build 1483040, red on PR), including 9 WinUI CollectionView tests (ValidateDynamic*) that fail with an identical OneTimeSetUp fixture-level timeout — their pattern is consistent with infrastructure flakiness, and the PR scope (Android ScrollView only) does not intersect WinUI CollectionView, but the deterministic regression cannot be dismissed without human confirmation. CI is also incomplete with 23 pending checks and 1 cancelled device-test check. Coverage: 138 checks · 101 passing/neutral/skipped · 14 failing · 23 pending · 0 inaccessible · 1 unmapped · 19 unexplained build legs · 0 unaccounted failing checks · 1 aborted failing checks · 0 canceled-build checks · 2 device-test unverified · 21 unattributed · 10 regressed-vs-base. Deterministic ceiling: Not ready — 23 pending checks; 1 unmapped failing check (Build Analysis); 19 unexplained build legs; 21 unattributed failures; 1 aborted failing check (maui-pr-devicetests MacCatalyst CoreCLR); 2 unverified device-test checks (XHarness exits 0 even on failure; no authenticated confirmation); 10 regressions vs base.
Recommended actionInvestigate the 10 regressions vs base before merging. The 9 ValidateDynamic* WinUI CollectionView tests and RemainingItemsThresholdReachedEventShouldTrigger all regressed on a check (WinUI CollectionView) whose scope does not overlap this Android-only PR — checking whether those failures also appear on the base branch in a fresh run would confirm infrastructure flakiness and allow dismissal. The cancelled MacCatalyst device-test check, 19 unexplained build legs, and 23 still-pending UI test checks must also complete before a final verdict is possible. Evidence detailsPR scope: 4 files changed; platform/android label; area-controls-scrollview. PR does not touch WinUI, CollectionView, or any iOS/macOS code. Build 1483591 (maui-pr-devicetests): link
Build 1483590 (maui-pr-uitests): link
Base-branch health: Recent base builds (1483186 for devicetests, 1483040 for uitests) both failed. The base branch is not clean; many iOS Picker/DatePicker/Editor failures are plausibly pre-existing but cannot be confirmed without a full baseline inspection. Build Analysis (unmapped check): documentation link — automated Arcade aggregator; no direct AzDO build ID available; must be reviewed manually. AzDO auth: Not available; authenticated test-run APIs were skipped. All data sourced from public build metadata, timelines, and log APIs. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e43b78a to
bdc062d
Compare
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ew (#35897) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event. ### Root Cause For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires. ### Description of Change Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #28064 ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/25384673-8f6f-4487-bc76-4f9c8dadb726" >| <video src="https://github.com/user-attachments/assets/9a043b15-4b65-4d18-bd9f-4c77aed5b322">| Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
TapGestureRecognizer attached to a horizontal ScrollView background does not fire on Android. Tapping the background area triggers no gesture event.
Root Cause
For horizontal/both orientation, MauiScrollView wraps content in a child MauiHorizontalScrollView, which always claims touch events. Android only invokes a view's touch listener when that view directly processes the event, so MauiScrollView's listener (where GesturePlatformManager hooks) never fires.
Description of Change
Override SetOnTouchListener in MauiScrollView to cache the listener in _touchListener. In MauiHorizontalScrollView.OnTouchEvent — called only when no child claimed the event — invoke _parentScrollView._touchListener?.OnTouch(...) before existing logic. This mirrors exactly when a vertical ScrollView's gesture fires.
Validated the behavior in the following platforms
Issues Fixed
Fixes #28064
Output ScreenShot
28064-BeforeFix.mov
28064-AfterFix.mov