[net11.0][Android] Implement handler based Shell architecture replacing legacy renderers#34758
Draft
Tamilarasan-Paranthaman wants to merge 26 commits intonet11.0from
Draft
[net11.0][Android] Implement handler based Shell architecture replacing legacy renderers#34758Tamilarasan-Paranthaman wants to merge 26 commits intonet11.0from
Tamilarasan-Paranthaman wants to merge 26 commits intonet11.0from
Conversation
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34758Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34758" |
Contributor
There was a problem hiding this comment.
Pull request overview
Implements a new handler-based Shell architecture for Android (opt-in via UseAndroidShellHandlers) and refactors shared Android navigation/tab/flyout infrastructure to reduce duplication with existing MAUI handlers/managers.
Changes:
- Added
RuntimeFeature.UseAndroidShellHandlers(defaultfalse) and MSBuild plumbing to enable the feature switch. - Introduced shared Android components/layouts (e.g.,
MauiDrawerLayout,TabbedViewManager,shellitemlayout.axml,shellsectionlayout.axml) and refactoredFlyoutViewHandler/TabbedPageManagerto use them. - Updated Shell compatibility components and test projects to validate the new Android Shell handlers in CI (plus a UI test stabilization tweak).
Reviewed changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/RuntimeFeature.cs | Adds UseAndroidShellHandlers runtime feature switch. |
| src/Core/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt | Public API updates for new tab abstractions/enums. |
| src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt | Public API updates including MauiDrawerLayout and handler signature changes. |
| src/Core/src/Primitives/TabBarPlacement.cs | Introduces TabBarPlacement enum. |
| src/Core/src/Platform/Android/Resources/values/styles.xml | Adds Android style for Shell TabLayout. |
| src/Core/src/Platform/Android/Resources/Layout/shellsectionlayout.axml | New Android layout used by ShellSection handler. |
| src/Core/src/Platform/Android/Resources/Layout/shellitemlayout.axml | New Android layout used by ShellItem handler. |
| src/Core/src/Platform/Android/Navigation/StackNavigationManager.cs | Adds navigation request queueing and Shell integration for per-tab containers. |
| src/Core/src/Platform/Android/MauiDrawerLayout.cs | New shared DrawerLayout wrapper used by FlyoutView/Shell. |
| src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cs | Refactors FlyoutViewHandler to use MauiDrawerLayout. |
| src/Core/src/Core/ITabbedView.cs | Expands ITabbedView to support shared tab management surface. |
| src/Core/src/Core/ITab.cs | Adds ITab abstraction for tab items. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/XFIssue/ShellSearchHandlerItemSizing.cs | Stabilizes screenshot capture via retry/tolerance. |
| src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj | Enables UseAndroidShellHandlers for UI test host app. |
| src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj | Enables UseAndroidShellHandlers for device tests. |
| src/Controls/src/Core/TabbedPage/TabbedPage.cs | Implements expanded ITabbedView surface on TabbedPage. |
| src/Controls/src/Core/Shell/ShellContent.cs | Propagates title updates to support handler-based tab title refresh. |
| src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt | Adds public handler types/methods for Android Shell handlers. |
| src/Controls/src/Core/Platform/Android/TabbedViewManager.cs | New shared manager for ViewPager2 + BottomNavigationView/TabLayout behavior. |
| src/Controls/src/Core/Platform/Android/TabbedPageManager.cs | Refactors TabbedPageManager to delegate tab UI logic to TabbedViewManager. |
| src/Controls/src/Core/Platform/Android/ITabbedViewSource.cs | Adds internal adapter interface to supply tab data without IView. |
| src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs | Conditionally registers Android Shell handlers based on runtime feature. |
| src/Controls/src/Core/Handlers/Shell/ShellTabbedViewAdapters.Android.cs | Adds Shell adapters bridging ShellItem/ShellSection to tab source model. |
| src/Controls/src/Core/Handlers/Shell/ShellHandler.Tizen.cs | Adds stub mappers to satisfy shared mapper entries. |
| src/Controls/src/Core/Handlers/Shell/ShellHandler.cs | Extends property mapper for Android/Tizen/Windows handler scenarios. |
| src/Controls/src/Core/Handlers/Shell/ShellHandler.Android.cs | New Android ShellHandler implementation built on MauiDrawerLayout. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs | Compatibility updates for toolbar/search behavior and back icon progress handling. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarAppearanceTracker.cs | Adds null-guard in SetAppearance. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellSearchViewAdapter.cs | Adds JNI ctor + null guard for filter publish. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutTemplatedContentRenderer.cs | Avoids double-updates when running under new handler path; exposes update methods. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRecyclerAdapter.cs | Adds additional null/dispose safety. |
| src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.targets | Maps MSBuild property to runtime feature switch. |
src/Core/src/Platform/Android/Navigation/StackNavigationManager.cs
Outdated
Show resolved
Hide resolved
9661c82 to
3e7bde8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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!
Description
ShellRenderer,ShellFlyoutRenderer,ShellItemRenderer,ShellSectionRenderer) with new handler classes that reuse standard MAUI platform components. The new architecture follows the same patterns used byFlyoutViewHandler,NavigationViewHandler, andTabbedPageManager, achieving the long-standing architectural goal of building Shell from the same building blocks as non-Shell features.Platform: Android only. iOS/MacCatalyst continue to use legacy
ShellRenderer.Motivation
The legacy Shell renderers on Android are monolithic, tightly coupled, and duplicate functionality that already exists in standard MAUI handlers:
ShellFlyoutRendererextendsDrawerLayoutdirectly (IS-A relationship) — duplicatesFlyoutViewHandlerdrawer logicShellItemRenderermanages its ownBottomNavigationView— duplicatesTabbedPageManagertab logicShellSectionRenderermanages its own toolbar, navigation stack, and content tabs — duplicatesNavigationViewHandlerandTabbedPageManagerpatternsThe new handler architecture:
MauiDrawerLayout— same shared component asFlyoutViewHandlerTabbedViewManager— shared tab management for both Shell andTabbedPagenavigationlayout.axml,shellitemlayout.axml,shellsectionlayout.axml)Shell → ShellHandler,ShellItem → ShellItemHandler,ShellSection → ShellSectionHandlerArchitecture Overview
Handler Hierarchy
Key Design Decisions
layout_weight.NavigationViewHandler/FlyoutViewHandlerpatterns. Resolves?attr/theme tokens at inflation time. Developers can override via Android resource overlays.FragmentStateAdaptersave/restore which causes crashes (fragments lose MAUI state). Same approach asTabbedPageRenderer.ShellItemHandlerAdapterandShellSectionHandlerAdapterimplementIShellItemRenderer/IShellSectionRenderer, maintaining compatibility withShellToolbarTrackerand appearance trackers.ITabbedViewSourceinterfaceITabbedView(which extendsIView). Lets Shell adapters provide tab data toTabbedViewManagerwithout 40+IViewstub members.New Files
Core Layer (
src/Core/)Platform/Android/MauiDrawerLayout.csDrawerLayoutwrapper forFlyoutViewHandlerandShellHandler. Supports three layout modes:Flyout,SideBySide,Padding. Implements flyout width calculation per Material Design guidelines.Platform/Android/Resources/Layout/shellitemlayout.axmlShellItemHandler—CoordinatorLayout+ViewPager2. Toolbar, tabs, andBottomNavigationViewplaced into NRM slots.Platform/Android/Resources/Layout/shellsectionlayout.axmlShellSectionHandler—LinearLayout+ViewPager2.Core/ITab.csITabinterface —Title,Icon,IsEnabledfor tab items inITabbedView/ITabbedViewSource.Primitives/TabBarPlacement.csTabBarPlacementenum —Top/Bottom.Controls Layer (
src/Controls/)Handlers/Shell/ShellHandler.Android.csMauiDrawerLayoutwithnavigationlayout.axml. Manages flyout content, scrim brushes (including gradient viaScrimBrushDrawable), flyout behavior modes. ImplementsIShellContextto create handler-based renderers.Handlers/Shell/ShellItemHandler.Android.csTabbedViewManager, shared toolbar (persists across section switches), ViewPager2 for section fragments, appearance tracking.Handlers/Shell/ShellSectionHandler.Android.csShellContent). TabLayout visibility controlled by item count. EachShellContentgets its ownStackNavigationManagerfor independent navigation.Handlers/Shell/ShellTabbedViewAdapters.Android.csShellItemTabbedViewAdapter(bottom tabs),ShellSectionTabbedViewAdapter(top tabs),ShellSectionTab,ShellContentTab. Bridge Shell data model toITabbedViewSourceforTabbedViewManager.Platform/Android/ITabbedViewSource.csTabbedViewManagerconsumers. Same shape asITabbedViewbut doesn't extendIView.Platform/Android/TabbedViewManager.csTabbedPageManager,ShellItemHandler, andShellSectionHandler.Modified Files
Handler Registration
Hosting/AppHostBuilderExtensions.csUseAndroidShellHandlers=true, legacyShellRendererotherwise.Handlers/Shell/ShellHandler.csOpt-In Infrastructure
Core/RuntimeFeature.csUseAndroidShellHandlersfeature switch (default:false). Follows the same pattern asUseMaterial3.Build.Tasks/.../Microsoft.Maui.Controls.targetsUseAndroidShellHandlersMSBuild property to the runtime feature switch.Shared Component Extraction
Handlers/FlyoutView/FlyoutViewHandler.Android.csMauiDrawerLayoutinstead of inlineDrawerLayoutlogic. Drawer functionality extracted to sharedMauiDrawerLayout.Platform/Android/TabbedPageManager.csTabbedViewManagerfor tab management. Reduced from ~984 lines of duplicated logic to delegating to the shared manager.Platform/Android/Navigation/StackNavigationManager.csCore Interfaces
Core/ITabbedView.csTabs,CurrentTab,BarBackgroundColor,BarBackground,BarTextColor,UnselectedTabColor,SelectedTabColor,TabBarPlacement,OffscreenPageLimit,IsSwipePagingEnabled,IsSmoothScrollEnabled,TabsChangedevent.Compatibility Layer Fixes
ShellFlyoutTemplatedContentRenderer.csIShellContextprovides handler-based adapters while keeping the same flyout content rendering.ShellFlyoutRecyclerAdapter.csShellSearchViewAdapter.csCustomFilterinner class — required for Android runtime to instantiate via reflection.ShellToolbarTracker.csShellToolbarAppearanceTracker.csVirtual View Changes
Element/Element.csShell/ShellContent.csTabbedPage/TabbedPage.csITabbedViewinterface members.Style.csPublicAPI
Updated
PublicAPI.Unshipped.txtfiles across all TFMs for new public types and interface members:MauiDrawerLayout,MauiDrawerLayout.FlyoutLayoutModeITab,ITabbedViewexpanded membersTabBarPlacementenumShellHandler,ShellItemHandler,ShellSectionHandlerhandler typesShared Infrastructure Summary
The PR achieves the core architectural goal — Shell now uses the same building blocks as non-Shell features:
MauiDrawerLayoutShellHandler(flyout drawer)FlyoutViewHandler(FlyoutPage)TabbedViewManagerShellItemHandler(bottom tabs),ShellSectionHandler(top tabs)TabbedPageManager(TabbedPage)StackNavigationManagerShellSectionHandler(per-content nav stack)NavigationViewHandler(NavigationPage)navigationlayout.axmlShellHandler(content root)FlyoutViewHandler,NavigationViewHandlerITab/ITabbedViewTabbedPageFragment Architecture
Shell handlers use wrapper fragments to integrate with Android's
FragmentManager:All fragment subclasses have default constructors for Android's
Fragment.instantiate()reflection requirement, with null guards inOnCreateView()for graceful restoration handling.Opt-In Mechanism
The Shell on Android now supports both the legacy renderer-based approach and the new handler-based approach, controlled by the
UseAndroidShellHandlersMSBuild property (following the same pattern asUseMaterial3).How to Enable
Or via command line:
dotnet build -p:UseAndroidShellHandlers=trueFlow
UseAndroidShellHandlersMSBuild property → build targets →AppHostBuilderExtensionsconditionally registers handlers or legacyShellRenderer.What Changes When Enabled
UseAndroidShellHandlers=true)ShellRendererShellHandler→MauiDrawerLayoutShellItemRendererShellItemHandler→ViewPager2+TabbedViewManagerShellSectionRendererShellSectionHandler→ViewPager2+StackNavigationManagerTesting
UseAndroidShellHandlers=trueis set in the following test/sample projects for CI validation:Controls.TestCases.HostApp.csproj— UI testsControls.DeviceTests.csproj— Device testsIssues Fixed
Fixes #32985