[.NET 11] [Android] Implemented material3 support for CarouselView - #35640
[.NET 11] [Android] Implemented material3 support for CarouselView#35640Dhivya-SF4094 wants to merge 13 commits into
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35640Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35640" |
|
/review -b feature/refactor-copilot-yml |
1 similar comment
|
/review -b feature/refactor-copilot-yml |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 6 findings
See inline comments for details.
This comment has been minimized.
This comment has been minimized.
kubaflo
left a comment
There was a problem hiding this comment.
Could you check the ai's suggestions?
4b948d7 to
90d2165
Compare
|
/review -b feature/enhanced-reviewer -p android |
This comment has been minimized.
This comment has been minimized.
922ec1a to
101cb69
Compare
|
/review rerun |
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 6 findings
See inline comments for details.
|
/review -b feature/enhanced-reviewer -p android |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/Controls/src/Core/Handlers/Items2/Android/MauiCarouselRecyclerView2.cs:120
UpdateSnapBehaviorattachesCarouselSnapHelperfor all non-None snap settings, but Material'sCarouselSnapHelperalways center-snaps and doesn't support MAUI'sSnapPointsAlignment(Start/End) or the full set ofSnapPointsTypebehaviors. Since this is a behavioral difference when Material3 is enabled, it should be explicitly documented here to avoid confusion when those properties appear to be ignored.
// Honor SnapPointsType.None: when the user disables snapping, leave the carousel
// free-scrolling instead of forcing Material's page snap. This mirrors the legacy
// SnapManager behavior (see Items/Android/SnapHelpers/SnapManager.cs).
if (ItemsLayout is Microsoft.Maui.Controls.ItemsLayout { SnapPointsType: SnapPointsType.None })
{
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines: Successfully started running 2 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check if test failures are related?
This comment has been minimized.
This comment has been minimized.
Tests Failure Analysis
Test Failure Review: Not ready - click to expandOverall verdict: Not ready. Of 40 distinct failures, 3 legs are deterministic regressions vs the base
Coverage: 141 checks · 123 passing · 18 failing · 0 pending · 0 inaccessible · 1 unmapped · 22 unexplained build legs · 0 unaccounted failing checks · 2 aborted failing checks · 0 canceled-build checks · 3 device-test unverified · 37 unattributed · 3 regressed-vs-base. Deterministic ceiling: Not ready — 3 legs regressed vs base, plus unexplained/aborted/unverified legs forbid a green verdict. Builds (this PR): maui-pr 1532716, maui-pr-devicetests 1532751, maui-pr-uitests 1532750. Base sampling (net11.0, 5 recent builds per definition): maui-pr 1535343, maui-pr-devicetests 1535345, maui-pr-uitests 1535443. Recommended actionA human should investigate the 3 regressed-vs-base legs ( Visual failure comparisonsFull-resolution CI baseline, actual, and diff images are embedded below. They supplement the failure classification and do not change the deterministic verdict ceiling.
|
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_PresentationModeModalNotAnimated - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_PresentationModeModalAnimated - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_PresentationModeModal - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_PresentationModeAnimated - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_PresentationModeNotAnimated - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_IsVisibleTrue - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_IsVisibleFalse - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_ShowTitleViewHidden - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
ShellPages_ShowTitleView - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
![]() |
![]() |
![]() |
EnsureFlyoutIconWithForegroundColor - macos - Needs human investigation - visual comparison
CI reported size differs - baseline is 789x563 pixels, actual is 1920x1051 pixels in build 1532750.
Relationship to PR: Needs human investigation - No decisive exact test-and-platform baseline attribution was available.
| CI baseline | Fresh PR actual | CI diff |
|---|---|---|
This comment has been minimized.
This comment has been minimized.
|
/azp run |
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.
Suppressed comments (2)
src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs:52
IsLoopEnabledwas introduced so subclasses (e.g., the Material3 carousel) can force the non-loop code paths, butUpdateLoop()later in this file still branches onCarousel.Loopdirectly (e.g.,var loopValue = Carousel.Loop;andif (Carousel.Loop)). That means a subclass overridingIsLoopEnabled => falsecan still hit loop-specific logic whenCarouselView.Loopchanges, which can reintroduce the virtual-loop behavior this abstraction is meant to prevent.
// Subclasses backed by a layout manager that has no virtual-range concept
// (e.g. Material's CarouselLayoutManager) can override this to force the
// non-loop code paths regardless of the public Carousel.Loop value.
protected virtual bool IsLoopEnabled => Carousel?.Loop == true;
src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/Material3CarouselViewFeatureTests.cs:50
- These tests currently depend on state set up only in the first test (tapping
CarouselViewButtonto enter the carousel scenario). Since most tests start directly withOptions, they will fail if run individually or if the app resets between tests. To make the suite robust, add per-test setup that navigates into the CarouselView scenario and enableResetAfterEachTestfor a clean start each test; then remove the redundantCarouselViewButtonsteps from the first test.
public Material3CarouselViewFeatureTests(TestDevice device) : base(device)
{
}
[Test, Order(1)]
[Category(UITestCategories.Material3)]
public void Material3VerifyCarouselViewLoadsItems()
{
// Regression guard for #35637: the Material CarouselLayoutManager must lay out the
// real item count and render the first item instead of getting stuck on splash.
App.WaitForElement("CarouselViewButton");
App.Tap("CarouselViewButton");
App.WaitForElement(Options);
App.Tap(Options);
App.WaitForElement(Apply);
App.Tap(Apply);
App.WaitForElement("Item 1");
}
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check if test failures are related?
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@Dhivya-SF4094 — new AI review results are available based on this last commit:
c7a66fe.
🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix
Gate Result: ❌ FAILED
Platform: ANDROID · Base: net11.0 · Merge base: 5d366053
🩺 Test does not reproduce the bug — ran the same in both states (PASS without fix, PASS with fix). The repro test is not exercising the issue. Strengthen the test before reviewing the fix.
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Material3CarouselViewFeatureTests Material3CarouselViewFeatureTests |
❌ PASS — 3093s | ✅ PASS — 583s |
🔴 Without fix — 🖥️ Material3CarouselViewFeatureTests: PASS ❌ · 3093s
Error-relevant lines (filtered from the build log):
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/37.0.0-ci.main.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: Xamarin.Android.Tasks.FastDeployInstallException: Serving... [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: Performing Incremental Install [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: Performing Streamed Install [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: All files should be loaded. Notifying the device. [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: Timed out waiting for data from device. [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: adb: failed to install /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net11.0-android/com.microsoft.maui.uitests-Signed.apk: 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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy2.InstallApkWithRetry(String apkFile, Boolean reinstall, Boolean testOnly, String user) [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy2.InstallPackage() [/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.2160/tools/Xamarin.Android.Common.Debugging.targets(378,5): error ADB0010: at Xamarin.Android.Tasks.FastDeploy2.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net11.0-android]
Build FAILED.
🟢 With fix — 🖥️ Material3CarouselViewFeatureTests: PASS ✅ · 583s
(no coded error found; showing last 1200 chars)
08/02/2026 20:17:54 Material3VerifyCarouselViewWithScrollTo Stop
Passed Material3VerifyCarouselViewWithScrollTo [5 s]
>>>>> 08/02/2026 20:17:54 Material3VerifyCarouselViewWithScrollToAndCurrentItem Start
>>>>> 08/02/2026 20:18:00 Material3VerifyCarouselViewWithScrollToAndCurrentItem Stop
Passed Material3VerifyCarouselViewWithScrollToAndCurrentItem [5 s]
>>>>> 08/02/2026 20:18:00 Material3VerifyCarouselViewWithVerticalLayout Start
>>>>> 08/02/2026 20:18:06 Material3VerifyCarouselViewWithVerticalLayout Stop
Passed Material3VerifyCarouselViewWithVerticalLayout [6 s]
>>>>> 08/02/2026 20:18:06 Material3VerifyCarouselViewWithVerticalLayoutAndKeepItemInView Start
>>>>> 08/02/2026 20:18:12 Material3VerifyCarouselViewWithVerticalLayoutAndKeepItemInView Stop
Passed Material3VerifyCarouselViewWithVerticalLayoutAndKeepItemInView [6 s]
NUnit Adapter 4.5.0.0: Test execution complete
Results File: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Material3CarouselViewFeatureTests.trx
Test Run Successful.
Total tests: 17
Passed: 17
Total time: 2.0595 Minutes
>>> TRX_RESULT_FILE: /home/vsts/work/1/s/CustomAgentLogsTmp/UITests/TestResults/Material3CarouselViewFeatureTests.trx
⚠️ Failure Details
- ❌ Material3CarouselViewFeatureTests PASSED without fix (should fail) — tests don't catch the bug
📁 Fix files reverted (4 files)
src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cssrc/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cssrc/Controls/src/Core/Hosting/AppHostBuilderExtensions.cssrc/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
New files (not reverted):
src/Controls/src/Core/Handlers/Items2/Android/Adapters/CarouselViewAdapter2.cssrc/Controls/src/Core/Handlers/Items2/Android/CarouselViewOnScrollListener2.cssrc/Controls/src/Core/Handlers/Items2/Android/MaskableCarouselItemViewHolder.cssrc/Controls/src/Core/Handlers/Items2/Android/MaskableTextItemViewHolder.cssrc/Controls/src/Core/Handlers/Items2/Android/MauiCarouselRecyclerView2.cssrc/Controls/src/Core/Handlers/Items2/CarouselViewHandler2.Android.cs
📱 UI Tests — CarouselView,CollectionView,Material3
Detected UI test categories: CarouselView,CollectionView,Material3
❌ Deep UI tests — 726 passed, 19 failed across 3 categories on platform-pool agent (replaces in-process counts above). 318 new snapshot tests need a baseline PNG (added separately by a maintainer — not a regression).
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
CarouselView |
90/91 (1 ❌) | 2 diff PNGs |
CollectionView |
612/630 (18 ❌) | — |
Material3 |
24/342 (318 ⚠ new baseline) | — |
🔍 AI analysis of failures — PR-related vs unrelated
🔍 AI-generated triage (GitHub Copilot CLI) — a heuristic judgement of whether each deep UI test failure is connected to this PR's changes. Verify before relying on it.
Mixed / uncertain: see the grouped assessment below.
- ✗ PR-related — Android CarouselView / Material3 carousel handler visual behavior (~1 test): the PR directly changes Android CarouselView handler code, loop handling, snap/listener behavior, and Material3 carousel adapter/layout plumbing, so the
VerticalCarouselMandatorySingleSnapAdvancesOneCardsnapshot difference is plausibly connected. - ℹ Uncertain — Android CollectionView scroll-to timeouts (~16 tests): the PR touches shared Android
MauiCarouselRecyclerViewbase code but not Android CollectionView itself, while these failures are the common “timed out waiting for element” scroll/flakiness pattern, so the evidence is weak and indirect. - ● Unrelated — Android CollectionView stale element (~1 test):
StaleElementReferenceExceptiononCollectionViewHeaderShouldNotScrollis a known nondeterministic Appium/DOM-refresh pattern and the PR does not change CollectionView header behavior. - ● Unrelated — Material3 non-carousel missing snapshot baselines (310+ tests): these fail with “Baseline snapshot not yet created” across DatePicker, Button, Slider, ImageButton, SearchBar, Label, and other Material3 controls outside the PR’s changed handler/test area, indicating missing Android snapshot baselines rather than a functional regression from this PR.
Strongest signal: only the CarouselView snapshot failure overlaps the PR’s Android CarouselView/Material3 handler changes; the large Material3 set is baseline creation noise and the CollectionView rows mostly match flaky timeout/stale-element patterns.
❌ CarouselView — 1 failed test
VerticalCarouselMandatorySingleSnapAdvancesOneCard
VisualTestUtils.VisualTestFailedException :
Snapshot different than baseline: VerticalCarouselMandatorySingleSnapAdvancesOneCard.png (4.87% difference)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.
More info: https://aka.ms/visual-test-workflow
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
at Microsoft.Maui.TestCases.Tests.Issues.Issue33308.VerticalCarouselMandatorySingleSnapAdvancesOneCard() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33308.cs:line 26
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, Bi
...
❌ CollectionView — 18 failed tests
VerifyGroupIndexScrollToByIndexWithEndPositionAndHorizontalGrid_Potato
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithEndPositionAndHorizontalGrid_Potato() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3170
at System.Reflec
...
VerifyGroupItemScrollToByIndexWithEndPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupItemScrollToByIndexWithEndPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3561
at System.RuntimeMe
...
VerifyScrollToByIndexWithEndPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyScrollToByIndexWithEndPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2376
at System.RuntimeMethodHandl
...
VerifyScrollToByIndexWithMakeVisiblePositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyScrollToByIndexWithMakeVisiblePositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2137
at System.RuntimeMet
...
VerifyScrollToByItemWithStartPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyScrollToByItemWithStartPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2541
at System.RuntimeMethodHand
...
VerifyGroupIndexScrollToByIndexWithStartPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithStartPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2918
at System.Reflec
...
CollectionViewHeaderShouldNotScroll
OpenQA.Selenium.StaleElementReferenceException : Cached elements 'By.id: com.microsoft.maui.uitests:id/HeaderEntry' do not exist in DOM anymore; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse, String commandToExecute)
at OpenQA.Selenium.WebDriver.ExecuteAsync(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.WebDriver.InternalExecute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.WebElement.Execute(String commandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.WebElement.get_Location()
at OpenQA.Selenium.Appium.AppiumElement.get_Rect()
at UITest.Appium.AppiumGeneralActions.GetRect(IDictionary`2 parameters) in /_/src/TestUtils/src/UITest.Appium/Actions/AppiumGeneralActions.cs:line 51
at UITest.Appium.AppiumGeneralActions.Execute(St
...
VerifyGroupIndexScrollToByIndexWithCenterPositionAndVerticalList_Potato
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithCenterPositionAndVerticalList_Potato() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 1874
at System.Refle
...
VerifyGroupIndexScrollToByIndexWithStartPositionAndVerticalList_Carrot
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithStartPositionAndVerticalList_Carrot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 1838
at System.Runtim
...
VerifyGroupItemScrollToByIndexWithEndPositionAndHorizontalGrid_Potato
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupItemScrollToByIndexWithEndPositionAndHorizontalGrid_Potato() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3597
at System.Runtime
...
VerifyGroupIndexScrollToByIndexWithCenterPositionAndHorizontalList_Tomato
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithCenterPositionAndHorizontalList_Tomato() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3026
at System.Ref
...
VerifyGroupItemScrollToByItemWithMakeVisiblePositionAndVerticalList_Apricot
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupItemScrollToByItemWithMakeVisiblePositionAndVerticalList_Apricot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 1943
at System.R
...
VerifyGroupItemScrollToByItemWithCenterPositionAndVerticalList_Potato
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupItemScrollToByItemWithCenterPositionAndVerticalList_Potato() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2007
at System.Runtime
...
VerifyGroupItemScrollToByIndexWithMakeVisiblePositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupItemScrollToByIndexWithMakeVisiblePositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3241
at System.R
...
VerifyScrollToByItemWithEndPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyScrollToByItemWithEndPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2715
at System.RuntimeMethodHandle
...
VerifyGroupIndexScrollToByIndexWithMakeVisiblePositionAndVerticalList_Apricot
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithMakeVisiblePositionAndVerticalList_Apricot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 1802
at System
...
VerifyGroupIndexScrollToByIndexWithEndPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyGroupIndexScrollToByIndexWithEndPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 3134
at System.Reflecti
...
VerifyScrollToByIndexWithStartPositionAndHorizontalList_Kiwi
System.TimeoutException : Timed out waiting for element...
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 2761
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 2788
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 797
at Microsoft.Maui.TestCases.Tests.CollectionView_ScrollingFeatureTests.VerifyScrollToByIndexWithStartPositionAndHorizontalList_Kiwi() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/CollectionView_ScrollingFeatureTests.cs:line 2214
at System.RuntimeMethodHan
...
⚠️ Material3 — 318 new snapshot tests need a baseline PNG
These tests call VerifyScreenshot but their baseline image isn't committed yet (brand-new snapshot tests get their baseline added separately by a maintainer). There's nothing to compare against, so this is not a regression — download the drop-deep-uitests artifact, confirm the rendering, and commit the baseline PNG.
Material3DatePicker_SetFontAttributesAndFormat_f_VerifyVisualStateVerifyMaterial3Button_SetShadowAndTextMaterial3Slider_SetMinTrackAndMaxTrackColor_VerifyVisualStateMaterial3Slider_ChangeThumbColor_VerifyVisualStateVerifyMaterial3ImageButtonAspect_AspectFitWithImageSourceFromFileSearchBar_Material3_SetPlaceholderAndVerticalTextAlignment_VerifyVisualStateMaterial3Label_VerifyLabelWithTextAndLineBreakModeMiddleTruncationSearchBar_Material3_InitialState_VerifyVisualStateMaterial3Label_VerifyLabelWithTextAndCharacterSpacingVerifyMaterial3Button_SetPaddingAndTextMaterial3RadioButton_FlowDirectionAndContent_VerifyVisualStateSearchBar_Material3_SetCancelButtonAndTextColor_VerifyVisualStateVerifyMaterial3ImageButtonWithBorderColorVerifyMaterial3Button_SetLineBreakModeHeadTruncationVerifyMaterial3ImageAspect_CenterWithFontImageSourceMaterial3Label_VerifyLabelWithFormattedTextWhenLineBreakModeTailTruncationVerifyMaterial3ImageAspect_CenterWithStreamSourceMaterial3DatePicker_SetDateAndIsVisible_VerifyVisualStateVerifyMaterial3Button_SetBorderWidthAndLineBreakModeMaterial3RadioButton_Checking_Default_Configuration_VerifyVisualStateMaterial3Editor_VerifyEditorTextWhenCharacterSpacingSetValuesMaterial3Slider_SetIsEnableAndMaxTrackColor_VerifyVisualStateMaterial3ProgressBar_ProgressToMethod_VerifyVisualStateMaterial3Editor_VerifyEditorControlWhenPlaceholderTextSetSearchBar_Material3_SetFontAttributesAndFontFamily_VerifyVisualStateMaterial3Label_VerifyLabelWithTextTypeAndLineBreakModeNoWrapMaterial3Switch_SetToggledAndOnColor_VerifyVisualStateMaterial3Entry_TextColor_VerifyVisualStateVerifyMaterial3ImageAspect_FillWithFontImageSourceMaterial3Entry_FontAttributes_VerifyVisualState
(+288 more — see TRX in artifact)
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)
📋 Pre-Flight — Context & Validation
Issue: #35637 - [Android] Implement material3 support for CarouselView
PR: #35640 - [Android] Implemented material3 support for CarouselView
Platforms Affected: Android Material3
Files Changed: 10 implementation/instruction/API, 1 test
Key Findings
- The PR adds a Material3 Android CarouselView handler using
CarouselLayoutManagerandMaskableFrameLayoutwrappers to avoid the startup/layout hang from the legacy looped adapter scale. - The already-completed gate failed on Android Material3 UI tests: swipe to item 2 renders item 2, but
CurrentItemandPreviousItemlabels remain at item 1 / no previous item. - The likely failing seam is
CarouselViewOnScrollListener2.GetVisibleItemsIndex: it can render the snapped item without sending a scrolled event whoseCenterItemIndexmaps to that item. - The PR also intentionally disables or no-ops
Loop,PeekAreaInsets,ItemSpacing, and visual states for the Material3 handler, which remains a broader product/API decision.
Code Review Summary
Verdict: NEEDS_CHANGES
Confidence: low
Errors: 2 | Warnings: 1 | Suggestions: 0
Key code review findings:
- ✗ Android Material3
CarouselViewsilently loses defaultLoop=truebehavior becauseMauiCarouselRecyclerView2.IsLoopEnabledis forced false andCarouselViewAdapter2.ItemCountexposes the real count. - ✗ Android Material3 swipe does not update
CurrentItem/ previous-item state in CI; the new scroll listener does not publish the snapped item after gesture completion. - ⚠
PeekAreaInsets,ItemSpacing, and per-item visual state behavior become documented no-ops under the default Material3 handler.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35640 | Add Android Material3 CarouselView handler with real item count, MaskableFrameLayout holders, Material snap helper, and documented unsupported features. | ❌ FAILED (Gate) | Items2/Android/*, handler registration, tests |
Gate failed current/previous item propagation after swipe. |
🔬 Code Review — Deep Analysis
Code Review — PR #35640
Independent Assessment
What this changes: Adds an Android Material3 CarouselViewHandler2 using CarouselLayoutManager, wraps items in MaskableFrameLayout, routes Android Material3 CarouselView to the new handler, and disables/omits several existing CarouselView behaviors (Loop, PeekAreaInsets, ItemSpacing, visual states/VisibleViews).
Inferred motivation: Fix Android Material3 CarouselView startup/layout hangs caused by using the existing looped adapter scale with Material's carousel layout manager.
Reconciliation with PR Narrative
Author claims: The PR intentionally supports only FullScreenCarouselStrategy; Loop, PeekAreaInsets, ItemSpacing, and per-item visual states are documented as unsupported limitations.
Agreement/disagreement: The code matches the narrative, but the limitation is introduced behind the default Android Material3 handler registration. That silently changes existing public CarouselView behavior for apps that did not opt into losing those features.
Prior Review Reconciliation
| Prior ❌ Error Finding | Source | Status | Evidence |
|---|---|---|---|
Material3 handler disables/default-ignores CarouselView.Loop |
MauiBot inline reviews + expert reviewer | ❌ Unresolved | CarouselView.Loop defaults true; Android Material3 registers CarouselViewHandler2; MauiCarouselRecyclerView2.IsLoopEnabled => false; CarouselViewAdapter2.ItemCount returns real count. |
PeekAreaInsets no-op / unsupported |
MauiBot inline reviews | ❌ Unresolved / intentionally documented | MapPeekAreaInsets remains empty. |
ItemSpacing no-op / unsupported |
MauiBot inline reviews | ❌ Unresolved / intentionally documented | CreateSpacingDecoration returns NoOpItemDecoration. |
| Current/previous item state not updated after swipe | Current CI + prior related comments | ❌ Unresolved | Current Android Material3 UI tests fail after ScrollRight: CurrentItemLabel remains Item 1; PreviousItemLabel remains No previous item. |
Raw string items crash due unwrapped TextView |
MauiBot inline reviews | ✅ Fixed | MaskableTextItemViewHolder now wraps text content in MaskableFrameLayout. |
Blast Radius Assessment
- Runs for all instances: Yes —
AppHostBuilderExtensionsregistersCarouselViewHandler2for every Android Material3CarouselView. - Startup impact: Yes — handler registration and carousel measurement/layout run during page initialization.
- Static/shared state: No new global mutable state found, but public handler registration affects all Material3 apps.
External Output Contract
| Consumer token/pattern | Producer location | Producer emission condition | Consumer assumption | Ordinary negative case | Downstream effect |
|---|---|---|---|---|---|
| N/A | N/A | No changed code classifies external tool output by regex/string literal. | N/A | N/A | N/A |
CI Status
- Required-check result: fail / unable to use
gh pr checksbecauseghis unauthenticated; public GitHub Checks API shows Android Material3 UI failures on headc7a66fe. - Classification: PR-caused failure ❌ for Android Material3 UI tests.
Material3VerifyCarouselViewWithCurrentItemsandMaterial3VerifyCarouselViewWithPreviousItemfail after swipe. - Action taken: Used prior gate evidence supplied by the caller and public PR context; did not re-run the separate gate phase.
Findings
❌ Error — Default looping behavior is silently removed for Android Material3 CarouselView
src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs registers CarouselViewHandler2 for all Android Material3 CarouselViews, while MauiCarouselRecyclerView2.IsLoopEnabled => false and CarouselViewAdapter2.ItemCount exposes only the real item count. Since CarouselView.Loop defaults to true, existing apps stop wrapping at the ends simply by running with Material3 enabled.
❌ Error — Swipe does not update CurrentItem / previous-item state in current CI
The current Android Material3 UI run fails the PR's own carousel tests after a swipe: Material3VerifyCarouselViewWithCurrentItems leaves CurrentItemLabel at Item 1, and Material3VerifyCarouselViewWithPreviousItem leaves PreviousItemLabel at No previous item. This points at the new scroll/current-item propagation path (CarouselViewOnScrollListener2.GetVisibleItemsIndex) not publishing the snapped item after gesture completion.
⚠️ Warning — Several public CarouselView features become no-ops under the default Material3 handler
MapPeekAreaInsets is empty, CreateSpacingDecoration returns a no-op, and the handler explicitly does not drive visual states/VisibleViews. These may be conscious FullScreenCarouselStrategy tradeoffs, but because the handler is globally registered for Material3 CarouselView, existing apps using these public properties receive no runtime signal that the properties no longer work.
Failure-Mode Probing
- Default
Loop=truewith multiple items: Material3 handler ignores looping; user reaches the last item and cannot wrap. - Swipe from item 1 to item 2: CI shows labels stay on item 1 / no previous item, so state propagation is broken.
- Empty collection: code switches to
LinearLayoutManager; this appears addressed. - Handler disconnect/reconnect: snap helper is detached in
DisposeandTearDownOldElement. - Runtime property changes:
PeekAreaInsetsand spacing updates are deliberate no-ops; behavior requires human/API decision.
Verdict: NEEDS_CHANGES
Confidence: low
Summary: The code introduces a broad Android Material3 handler replacement with public behavior regressions, and current CI has PR-relevant Android Material3 CarouselView failures. The loop/default behavior regression and failing current-item propagation should be resolved before merge.
🛠️ Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Publish Material snap target directly on scroll idle from CarouselViewOnScrollListener2. |
❌ FAIL | 1 file | Test invocation failed before original assertion; approach also introduced a risky second state-publication path. |
| 2 | try-fix | Update CurrentItem from the existing shared Android CarouselViewScrolled path after Position is updated. |
✅ PASS | 1 file | Passed targeted Android Material3 CarouselView setup + current/previous item tests. |
| PR | PR #35640 | Add Material3 handler with real item count, Material snap helper, and MaskableFrameLayout item wrappers. | ❌ FAILED (Gate) | Multiple files | Original PR fixes startup/layout hang but gate failed current/previous item propagation after swipe. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Code review identified the failing seam as scroll/current-item propagation, not item rendering. |
| try-fix-1 failure | 1 | Yes | Avoid direct idle-time property publication; use existing scroll event pipeline. |
| try-fix-2 | 1 | No | Passing candidate found; no further materially different candidate needed for the gate failure. |
Exhausted: No — stopped because Candidate #2 passed all targeted regression tests and is demonstrably better than the PR's current fix for the failed gate.
Selected Fix: Candidate #2 — it fixes current/previous item propagation through the shared Android carousel state path with a one-line implementation change and no Material-specific lifecycle callback.
📝 Recommended PR Title & Description
Assessment: ✏️ Recommend updating — the current title is close but not in the preferred component/title form, and the description should include the winning current-item propagation fix while preserving the detailed Material3 limitations.
Recommended title
[Android] CarouselView: Implement Material3 support
Recommended description
### Description of Change
This pull request introduces Material Design Carousel support for Android `CarouselView` under Material3. It adds a Material3-specific handler path built around Material's `CarouselLayoutManager` and `FullScreenCarouselStrategy`, wraps carousel item roots in `MaskableFrameLayout`, and adjusts the shared Android carousel state path so gesture scrolling updates both `Position` and `CurrentItem`.
**Material Carousel Support and Adapter Enhancements:**
* Added `CarouselViewAdapter2`, a new adapter for `MauiCarouselRecyclerView2`, which wraps each item in a `MaskableFrameLayout` to satisfy Material's `CarouselLayoutManager` requirements. This adapter also disables virtual looping, exposing the real item count to avoid performance issues and infinite layout loops with the Material carousel. (`src/Controls/src/Core/Handlers/Items2/Android/Adapters/CarouselViewAdapter2.cs`)
* Introduced `MaskableCarouselItemViewHolder`, a view holder that manages MAUI content inside a `MaskableFrameLayout`, ensuring correct handling of item templates and data binding for the Material carousel. (`src/Controls/src/Core/Handlers/Items2/Android/MaskableCarouselItemViewHolder.cs`)
* Added `MaskableTextItemViewHolder` so raw string items (a `CarouselView` bound to plain strings with no `ItemTemplate`) are also wrapped in a `MaskableFrameLayout`, since `CarouselLayoutManager` rejects direct RecyclerView children that are not `MaskableFrameLayout`.
* Added `CarouselViewOnScrollListener2`, a scroll listener tailored for `MauiCarouselRecyclerView2` that works directly with `CarouselLayoutManager` and does not depend on the legacy loop manager.
* Updated the shared Android carousel scrolled path to publish `CurrentItem` after `Position` changes, so Material3 gesture scrolling updates `CurrentItem` and previous-item state consistently.
* The Material handler renders the EmptyView using a plain `LinearLayoutManager` instead of Material's `CarouselLayoutManager`. `MauiCarouselRecyclerView2.SelectLayoutManager` returns a `LinearLayoutManager` whenever the active adapter is the `EmptyViewAdapter`, because Material's keyline mask would collapse a normally-sized EmptyView.
**Loop Logic Improvements:**
* Refactored loop logic in `MauiCarouselRecyclerView` by introducing the `IsLoopEnabled` property, allowing subclasses to override loop behavior. `MauiCarouselRecyclerView2` overrides this to disable the legacy virtual looping path because Material's `CarouselLayoutManager` does not support the `LoopScale` virtual-range model.
> [!IMPORTANT]
> The Material3 path is locked to `FullScreenCarouselStrategy` (one item masked to the full viewport, snapping one page at a time). The following `CarouselView` behaviors are intentionally not supported under this strategy and are documented in code:
>
> - **`Loop` is not supported.** Material's `CarouselLayoutManager` has no virtual-range model, so the legacy `LoopScale` trick used by the `LinearLayoutManager` path causes infinite measure/GC loops. Handler2 forces non-loop behavior (`IsLoopEnabled => false`) and exposes the real item count. Keep `CarouselView.Loop=\"False\"`.
> - **`PeekAreaInsets` is not supported.** `FullScreenCarouselStrategy` masks every item to fill the viewport, so there is no peek of adjacent items. The mapper is a documented no-op and item sizing deliberately ignores the insets.
> - **`LinearItemsLayout.ItemSpacing` is not honoured.** Material's `CarouselLayoutManager` has no spacing API and builds its `KeylineState` from the decorated measured size of the first child, so injecting spacing offsets would distort the keyline geometry.
> - **Per-item visual states / `VisibleViews` are not supported.** The inherited visual-state machinery depends on `LinearLayoutManager` and direct `ItemContentView` children; the Material handler uses `CarouselLayoutManager` with `MaskableFrameLayout` roots.
### Issues Fixed
Fixes #35637
### Platforms Tested
- [x] Android
🏁 Report — Final Recommendation
Comparative Report — PR #35640 STEP 5a Candidates
Candidate Ranking
| Rank | Candidate | Regression result | Assessment |
|---|---|---|---|
| 1 | try-fix-2 |
✅ Passed targeted Android Material3 CurrentItem / PreviousItem tests |
Best candidate. It fixes the observed gate failure by adding SetCurrentItem(index) to the existing shared Android carousel scrolled pipeline after UpdatePosition(index), avoiding a second Material-specific state publication path. |
| 2 | pr-plus-reviewer |
Not independently re-run; analytically equivalent to try-fix-2 for the scroll-state finding |
Applying the expert reviewer's concrete feedback yields the same one-line current-item propagation fix as try-fix-2. It remains ranked below try-fix-2 because STEP 5a provides direct pass evidence for try-fix-2, while the sandbox candidate was not separately executed. |
| 3 | pr |
❌ Failed supplied gate / pre-flight evidence | The raw PR fixes the Material3 startup/layout hang and wraps Material carousel children correctly, but gesture scrolling does not update CurrentItem / previous-item state. |
| 4 | try-fix-1 |
❌ Failed | Adds a direct idle-time state publication path in CarouselViewOnScrollListener2; test execution failed before reaching the original assertion and the approach is lifecycle-riskier than reusing the shared scrolled pipeline. |
Candidate Details
pr
The submitted PR introduces the core Material3 CarouselView implementation: CarouselViewHandler2, MauiCarouselRecyclerView2, CarouselViewAdapter2, MaskableCarouselItemViewHolder, MaskableTextItemViewHolder, a Material-specific scroll listener, global Android Material3 handler registration, EmptyView layout-manager switching, and Material3 UI coverage.
It is not sufficient as submitted. The forced non-loop path in MauiCarouselRecyclerView.CarouselViewScrolled updates Position but not CurrentItem, so Android Material3 swipe tests render the next item while labels bound to CurrentItem / previous item remain stale. The raw PR also leaves the broader Loop=true compatibility issue unresolved.
pr-plus-reviewer
The expert reviewer produced two major inline findings in inline-findings.json:
- Publish
CurrentItemfrom the existing scroll pipeline after the non-loop Material3 path updatesPosition. - Resolve or explicitly reconsider the global removal of default
Loop=truebehavior for Android Material3 CarouselView.
The sandbox-applied concrete fix for finding 1 is the same as try-fix-2:
diff --git a/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs b/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
index 86a3811d81..acabced811 100644
--- a/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
+++ b/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
@@ -557,6 +557,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items
return;
UpdatePosition(index);
+ SetCurrentItem(index);
UpdateVisualStates();
}The loop finding is not safely fixable by re-enabling the legacy virtual range, because that would reintroduce the Material CarouselLayoutManager hang. It needs a separate design or an explicit product decision. Therefore pr-plus-reviewer is a valid improvement over pr for the failed gate, but it is not stronger than the empirically passing try-fix-2.
try-fix-1
try-fix-1 attempted to publish Position and CurrentItem directly from CarouselViewOnScrollListener2.OnScrollStateChanged when RecyclerView becomes idle. It failed the targeted invocation before reaching the original assertion and introduced a second state-publication path that can fire during setup or lifecycle transitions. It should not be selected.
try-fix-2
try-fix-2 updates MauiCarouselRecyclerView.CarouselViewScrolled to call the existing SetCurrentItem(index) helper immediately after UpdatePosition(index). This is the smallest fix for the actual failed seam: the scroll listener already computes the visible center index and the base carousel code already owns the cross-platform Position/CurrentItem state propagation. STEP 5a reports the targeted Android Material3 setup/current/previous-item tests passed with this change.
Winning Candidate
Winner: try-fix-2.
try-fix-2 is the only candidate with direct passing regression evidence, fixes the raw PR's observed gate failure, and does so through existing Android CarouselView state propagation rather than adding a Material-specific idle callback. It does not resolve the broader Loop=true compatibility concern, but every viable candidate that preserves the Material3 implementation shares that limitation; the passed regression fix is still required before the PR can proceed.
🧭 Next Steps — alternative fix proposed (try-fix-2)
Automated review — alternative fix proposed
The expert-reviewer evaluation compared the PR fix against automatically generated candidates and selected try-fix-2 as the strongest fix.
Why: try-fix-2 wins because it is the only candidate with direct passing Android Material3 regression evidence and it fixes the raw PR's missing CurrentItem/PreviousItem propagation through the existing shared CarouselView scrolled pipeline. The broader Loop=true compatibility concern remains unresolved, but the raw PR and try-fix-1 both failed the relevant regression path.
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-2)
diff --git a/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs b/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
index 86a3811d81..acabced811 100644
--- a/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
+++ b/src/Controls/src/Core/Handlers/Items/Android/MauiCarouselRecyclerView.cs
@@ -557,6 +557,7 @@ namespace Microsoft.Maui.Controls.Handlers.Items
return;
UpdatePosition(index);
+ SetCurrentItem(index);
UpdateVisualStates();
}
|
Reviewed the AI summary and confirmed that the reported concerns are not valid. |
@kubaflo We can hold this for now. We need to discuss the Material Carousel behavior further, as the new Material implementation will not support some existing MAUI APIs that users may expect to work. Please hold off on merging this PR until we confirm the behavior. |






























Description of Change
This pull request introduces a new implementation for Material Design Carousel support in the Android handler code, focusing on compatibility with Material's
CarouselLayoutManagerand its unique requirements. The most significant changes include the addition of new adapter and view holder classes that wrap carousel items in aMaskableFrameLayout, a new scroll listener tailored for Material's carousel, and several extensibility points in the base classes to support these requirements. There are also targeted refactors to enable more flexible handling of looping and empty views.Material Carousel Support and Adapter Enhancements:
CarouselViewAdapter2, a new adapter forMauiCarouselRecyclerView2, which wraps each item in aMaskableFrameLayoutto satisfy Material'sCarouselLayoutManagerrequirements. This adapter also disables virtual looping, exposing the real item count to avoid performance issues and infinite layout loops with the Material carousel. (src/Controls/src/Core/Handlers/Items2/Android/Adapters/CarouselViewAdapter2.cs)MaskableCarouselItemViewHolder, a view holder that manages MAUI content inside aMaskableFrameLayout, ensuring the correct handling of item templates and data binding for the Material carousel. (src/Controls/src/Core/Handlers/Items2/Android/MaskableCarouselItemViewHolder.cs)CarouselViewOnScrollListener2, a scroll listener tailored forMauiCarouselRecyclerView2that works directly withCarouselLayoutManagerand does not depend on the legacy loop manager. It accurately tracks visible items and snap positions.(src/Controls/src/Core/Handlers/Items2/Android/CarouselViewOnScrollListener2.cs)Loop Logic Improvements:
MauiCarouselRecyclerViewby introducing theIsLoopEnabledproperty, allowing subclasses to override loop behavior (for example, to disable looping when using a layout manager that does not support virtual looping), and replaced direct checks ofCarousel.LoopwithIsLoopEnabledthroughout the code.Important
The Material3 path is locked to
FullScreenCarouselStrategy(one item masked to the full viewport, snapping one page at a time). The followingCarouselViewbehaviors are intentionally not supported under this strategy and are documented in code:Fixed
Fixes #35637
Screenshots
35637_BeforeChanges.mov
35637_AfterChanges.mov
UI Test results