Skip to content

Conversation

@NanthiniMahalingam
Copy link
Contributor

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!

Root Cause

  • The Shell Flyout’s LinearLayoutManager configuration was overriding the ScrollLayoutManager settings, preventing the Shell.FlyoutVerticalScrollMode property from being correctly applied to the RecyclerView.

Description of Change

  • The LinearLayoutManager assignment for the Shell Flyout RecyclerView was removed so that the ScrollLayoutManager can correctly control scrolling behavior.
  • In Auto or Disabled scroll modes, the ScrollLayoutManager passed an EXACTLY heightMeasureSpec to the RecyclerView, causing first item to expand to the full height of the RecyclerView instead of using its natural height.
  • By setting measureHeight = true, the heightMeasureSpec switches to UNSPECIFIED, allowing items to measure at their natural height (~48dp). This ensures accurate scrolling behavior and allows the RecyclerView to create all required view holders properly.

Validated the behaviour in the following platforms

  • Android
  • Windows ,
  • iOS,
  • MacOS

Issues Fixed

Fixes #32477

Output

Android

Before After
32477_issue_android_before.mov
32477_issue_android_after.mov

@dotnet-policy-service dotnet-policy-service bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Nov 19, 2025
@sheiksyedm
Copy link
Contributor

PR Review: Fix Shell Flyout Scrolling with FlyoutVerticalScrollMode.Disabled

Summary

PR correctly fixes Shell flyout scrolling behavior when FlyoutVerticalScrollMode is set to Disabled on Android. The fix addresses two root causes: (1) duplicate LinearLayoutManager assignment was overriding ScrollLayoutManager configuration, and (2) items were measured incorrectly causing first item to expand to full height. The implementation is minimal, focused, and includes appropriate UI tests.


Code Review

Changes Overview

Files Modified:

  1. ShellFlyoutTemplatedContentRenderer.cs - Removed duplicate LinearLayoutManager assignment, added UpdateVerticalScrollMode call
  2. ShellFlyoutRecyclerAdapter.cs - Added MeasureHeight flag for Auto/Disabled scroll modes
  3. Issue32477.cs (HostApp) - Test page with 30 MenuItems and FlyoutVerticalScrollMode.Disabled
  4. Issue32477.cs (Shared.Tests) - Appium test verifying flyout doesn't scroll

Technical Analysis

Root Cause Identification: ✅ Excellent

  • PR description clearly explains the two issues:
    1. LinearLayoutManager configuration was overriding ScrollLayoutManager
    2. EXACTLY heightMeasureSpec caused items to expand to full RecyclerView height

Fix 1: Remove Duplicate LinearLayoutManager (Line 932)

// REMOVED:
SetLayoutManager(new LinearLayoutManager(context, (int)Orientation.Vertical, false));
  • ✅ Correct - This was overriding the ScrollLayoutManager set on line 932
  • ✅ The ScrollLayoutManager has custom CanScrollVertically() logic that respects FlyoutVerticalScrollMode
  • ✅ This change is backward compatible - ScrollLayoutManager extends LinearLayoutManager

Fix 2: Set MeasureHeight Flag (ShellFlyoutRecyclerAdapter.cs, lines 147-151)

if (_shellContext.Shell.FlyoutVerticalScrollMode != ScrollMode.Enabled)
{
    container.MeasureHeight = true;
}
  • ✅ Correct approach - Forces UNSPECIFIED measureSpec instead of EXACTLY
  • ✅ Only applies when mode is Auto or Disabled (not Enabled)
  • ✅ Good comment explaining WHY this is needed
  • ✅ Allows items to measure at natural height (~48dp) instead of expanding

Fix 3: Ensure UpdateVerticalScrollMode is Called (Line 313)

UpdateVerticalScrollMode();
  • ✅ Correct - Ensures scroll mode is applied after creating flyout content
  • ✅ This was missing before, causing scroll mode to not be applied until property changed

Code Quality

Positive Aspects:

  • ✅ Minimal, surgical changes (93 additions, 1 deletion)
  • ✅ Well-commented code explaining the technical reason
  • ✅ Follows existing patterns in the codebase
  • ✅ No breaking changes to public API
  • ✅ Platform-specific code properly isolated to Android folder

Suggestions for Improvement:

None - the code is clean and well-structured.


UI Test Review

Test Structure: ✅ Correct

HostApp Test Page (Issue32477.cs):

  • ✅ Properly inherits from TestShell
  • ✅ Has [Issue] attribute with correct tracker, number, description, and platform
  • ✅ Sets FlyoutVerticalScrollMode = ScrollMode.Disabled
  • ✅ Sets FlyoutBehavior = FlyoutBehavior.Locked (makes flyout visible for testing)
  • ✅ Adds 30 MenuItems to create scrollable content
  • ✅ Includes descriptive label in content page

Appium Test (Issue32477.cs):

  • ✅ Inherits from _IssuesUITest
  • ✅ Has descriptive test method name: VerifyFlyoutVerticalScrollModeDisabledOnAndroid()
  • ✅ Uses correct category: [Category(UITestCategories.FlyoutPage)]
  • ✅ Test logic: Attempts to scroll 5 times, then verifies Item 1 is still visible
  • ✅ Uses appropriate conditional compilation: #if TEST_FAILS_ON_WINDOWS

Test Category: ✅ Appropriate

  • Uses UITestCategories.FlyoutPage which is the correct category for flyout-related tests
  • Only one category per test (following guidelines)

Test Logic Analysis

The test verifies:

  1. Item 1 is visible initially
  2. Attempts to scroll down 5 times using ScrollDown with Gesture strategy
  3. Verifies Item 1 is still visible (proving flyout didn't scroll)

Potential Edge Cases to Consider:


Platform Coverage

Tested Platforms (per PR description):

  • ✅ Android (primary platform for this issue)
  • ✅ Windows
  • ✅ iOS
  • ✅ MacOS

Analysis:

  • ✅ Android is the primary affected platform (matches issue description)
  • ✅ Changes are Android-specific (in Android folder)
  • ✅ iOS has separate implementation in ShellFlyoutLayoutManager.cs (uses UIScrollView)
  • ✅ No breaking changes to cross-platform API

Edge Cases and Scenarios

Tested Scenarios:

  1. ✅ FlyoutVerticalScrollMode.Disabled with 30+ items
  2. ✅ FlyoutBehavior.Locked (visible flyout)

Edge Cases to Consider:

  1. Auto mode with varying content heights - Fixed by MeasureHeight flag
  2. Dynamic property changes - UpdateVerticalScrollMode() handles this
  3. Flyout with custom content template - Code handles both RecyclerView and custom content
  4. Rapid scrolling attempts - Test verifies with 5 scroll attempts

Additional Edge Cases (for future testing):

  • Switching between ScrollMode.Enabled, Auto, and Disabled at runtime
  • FlyoutBehavior.Flyout (hamburger menu) vs Locked
  • Very small screens where items might not fit
  • Accessibility/TalkBack navigation through flyout items

Breaking Changes

None - This is a bug fix with no API changes.


Documentation

XML Documentation: Not applicable - no public API changes

PR Description: ✅ Excellent

  • Clear explanation of root cause
  • Detailed description of changes
  • Videos showing before/after behavior
  • Platform testing checklist

Code Comments: ✅ Good

  • Added clear comment explaining the MeasureHeight flag logic
  • Comment references the technical reason (EXACTLY vs UNSPECIFIED measureSpec)

Security & Performance

Security: ✅ No concerns

  • No user input validation needed
  • No external data sources
  • Platform-specific UI behavior only

Performance: ✅ No concerns

  • MeasureHeight flag may slightly improve performance (avoids unnecessary re-layouts)
  • Removed duplicate LinearLayoutManager assignment reduces overhead
  • No allocations in hot paths

Comparison with Existing Solutions

Checked for duplicate PRs: No other open PRs addressing issue #32477

Consistency with iOS Implementation:

  • iOS uses different approach (UIScrollView.ScrollEnabled property)
  • Android uses custom ScrollLayoutManager with CanScrollVertically() override
  • Both approaches are platform-appropriate

Testing Results

Manual Testing: ⏸️ Not performed

  • Reason: No Android emulator available in current environment
  • PR author provided video evidence of fix working correctly
  • Code review confirms the logic is sound

Automated Testing: ⏸️ Not run locally

  • UI test structure is correct and follows guidelines
  • Test will run in CI pipeline
  • Test logic is appropriate for validating the fix

Code Analysis: ✅ Passed

  • All changes are logical and address the root causes
  • No obvious bugs or issues identified
  • Follows .NET MAUI coding standards

Issues Found

None

All aspects of the PR are correct and well-implemented.


Recommendations

For Merge: ✅ Approve

Rationale:

  1. ✅ Correctly identifies and fixes the root causes
  2. ✅ Minimal, focused changes with no side effects
  3. ✅ Includes proper UI tests in both HostApp and Shared.Tests
  4. ✅ Well-documented with clear comments and PR description
  5. ✅ No breaking changes
  6. ✅ Follows .NET MAUI coding standards and patterns
  7. ✅ Platform-specific code properly isolated

Confidence Level: High

  • Code review confirms the logic is correct
  • Root cause analysis is thorough and accurate
  • Changes are minimal and well-targeted
  • UI test structure follows guidelines
  • PR author tested on all platforms

Additional Notes

Strengths of this PR:

  1. Clear problem identification - PR description explains exactly what was wrong
  2. Targeted fix - Changes only what's necessary, nothing more
  3. Good comments - Explains WHY changes were made, not just WHAT
  4. Proper testing - Includes both manual testing (videos) and automated UI tests
  5. No scope creep - Stays focused on fixing issue [Android] Shell.FlyoutVerticalScrollMode="Disabled" does not disable scrolling #32477

For Future Enhancements (not blocking):

  • Consider adding UI tests for ScrollMode.Auto and ScrollMode.Enabled to ensure they still work
  • Consider testing dynamic changes between scroll modes at runtime

Checklist


Final Recommendation

APPROVE - Ready to merge

This PR correctly fixes the Shell flyout scrolling issue with a minimal, well-tested solution. The code is clean, well-documented, and follows all .NET MAUI guidelines.

@sheiksyedm sheiksyedm marked this pull request as ready for review November 20, 2025 12:05
Copilot AI review requested due to automatic review settings November 20, 2025 12:05
@sheiksyedm
Copy link
Contributor

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copilot finished reviewing on behalf of sheiksyedm November 20, 2025 12:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an Android-specific issue where the Shell flyout's vertical scroll mode setting (FlyoutVerticalScrollMode = ScrollMode.Disabled) was not being properly respected. The root cause was that a LinearLayoutManager was being assigned after the ScrollLayoutManager, overriding its scroll-control logic.

Key Changes:

  • Removed the redundant LinearLayoutManager assignment that was overriding ScrollLayoutManager settings
  • Added MeasureHeight = true flag when scroll mode is not Enabled, allowing RecyclerView items to measure at their natural height instead of expanding to full RecyclerView height
  • Added explicit call to UpdateVerticalScrollMode() after flyout content updates to ensure scroll settings are applied
  • Included UI tests to validate that flyout scrolling is properly disabled

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32477.cs NUnit test to verify that flyout scrolling is disabled when FlyoutVerticalScrollMode is set to Disabled
src/Controls/tests/TestCases.HostApp/Issues/Issue32477.cs Test page implementation creating a Shell with 30 menu items and disabled vertical scroll mode
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutTemplatedContentRenderer.cs Removed redundant LinearLayoutManager assignment and added UpdateVerticalScrollMode() call
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRecyclerAdapter.cs Added MeasureHeight = true flag for non-Enabled scroll modes to fix item measurement

public override string Issue => "[Android] Shell flyout does not disable scrolling when FlyoutVerticalScrollMode is set to Disabled";

[Test]
[Category(UITestCategories.FlyoutPage)]
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test category should be UITestCategories.Shell instead of UITestCategories.FlyoutPage. This test is specifically for Shell flyout behavior, not the FlyoutPage control. The Shell category is more appropriate for Shell-specific functionality.

Suggested change
[Category(UITestCategories.FlyoutPage)]
[Category(UITestCategories.Shell)]

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +31
Items.Add(new MenuItem
{
Text = $"Item {i}"
});
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the UI Testing Guidelines, MenuItem items in the HostApp test page should have AutomationId attributes set for proper test automation. The test tries to locate "Item 1" and "Item 5" via WaitForElement and ScrollDown, but the MenuItems created in the loop don't have AutomationId set. Add AutomationId = $"Item {i}" when creating each MenuItem to ensure the test can properly interact with these elements.

Copilot generated this review using guidance from repository custom instructions.
@@ -0,0 +1,30 @@

#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/32416
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TEST_FAILS_ON_WINDOWS conditional compilation directive with issue #32416 excludes this test from Windows. However, the PR description states the test was validated on Windows (checkbox is checked). Either the conditional directive should be removed if the test now works on Windows, or the PR description should clarify that Windows validation was skipped. Please verify the actual Windows test status and align the code with the description.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-shell Shell Navigation, Routes, Tabs, Flyout partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android shell-flyout

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Shell.FlyoutVerticalScrollMode="Disabled" does not disable scrolling

3 participants