-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fixed Shell TitleView disappears when switching between tabs on Android #33469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Hey there @@KarthikRajaKalaimani! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this 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 a regression in .NET MAUI 9.0.30 where Shell TitleView disappears when switching between tabs on Android. The fix ensures that when a fragment becomes visible after being hidden (during tab switching), the TitleView is properly refreshed.
Changes:
- Added
OnHiddenChangedoverride inShellSectionRendererto update TitleView when fragment becomes visible - Stored
Toolbarreference as field to enable TitleView updates during fragment visibility changes - Added UI test to verify TitleView persists when switching tabs
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
ShellSectionRenderer.cs |
Stores Toolbar reference as _shellToolbar field and overrides OnHiddenChanged to update TitleView when fragment becomes visible after tab switch |
PublicAPI.Unshipped.txt |
Documents the new public API method OnHiddenChanged override for Android |
Issue33304.cs (HostApp) |
Implements test page with Shell containing multiple tabs and a TitleView to reproduce the issue |
Issue33304.cs (Tests) |
Adds automated UI test that switches tabs and verifies TitleView persists |
| { | ||
| base.OnHiddenChanged(hidden); | ||
|
|
||
| if (!hidden) |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null reference exception if _shellToolbar or _shellToolbar.Handler is null. The OnHiddenChanged method can be called before OnCreateView (where _shellToolbar is initialized) or after disposal (where it's not explicitly set to null). Add null checks: if (!hidden && _shellToolbar?.Handler != null).
| if (!hidden) | |
| if (!hidden && _shellToolbar?.Handler != null) |
|
|
||
| if (!hidden) | ||
| { | ||
| _shellToolbar.Handler.UpdateValue("TitleView"); |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a magic string "TitleView" instead of nameof(Toolbar.TitleView) makes the code fragile to refactoring. Use nameof(Toolbar.TitleView) for type safety and consistency with the rest of the codebase (see line 630 in ShellToolbarTracker.cs which uses nameof(Toolbar.TitleView)).
| Text = "TitleView", | ||
| AutomationId = "HomeTitleView" | ||
| }); | ||
| // Shell.SetFlyoutBehavior(FlyoutBehavior.Disabled); |
Copilot
AI
Jan 16, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented-out code. If this line was used during development/testing, it should either be removed or uncommented with a comment explaining why it's needed for the test.
| // Shell.SetFlyoutBehavior(FlyoutBehavior.Disabled); |
🤖 AI Summary📊 Expand Full Review🔍 Pre-Flight — Context & Validation📝 Review Session — Added null check for handler ·
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Post delayed UpdateTitleView() in ShellToolbarTracker.OnShellNavigated() when ShellSectionChanged |
❌ FAIL | ShellToolbarTracker.cs (+12) |
Navigation event fires before fragment visibility change completes |
| PR | PR #33469 | Override OnHiddenChanged to update TitleView handler when fragment becomes visible |
✅ PASS (Gate) | ShellSectionRenderer.cs (+16), PublicAPI.Unshipped.txt (+1) |
Original PR - uses fragment lifecycle |
Try-Fix Attempt #1 Analysis:
- Approach: Modified
ShellToolbarTracker.OnShellNavigated()to post a delayedUpdateTitleView()call when navigation source isShellSectionChanged - Why it failed:
OnShellNavigatedfires before fragment visibility change completes. Even posting via_platformToolbar.Post()doesn't work because:- Navigation events fire at navigation start, not at fragment visibility change
- A single
Post()delays by only one message queue cycle - insufficient for fragment transition - No direct access to fragment lifecycle from
ShellToolbarTracker
Exhausted: Yes - Alternative approaches from navigation event system cannot reliably fix this issue because they don't have visibility into fragment lifecycle timing. The PR's OnHiddenChanged approach is the correct solution.
Selected Fix: PR's fix - OnHiddenChanged override is the optimal location because:
- It fires at the exact moment when fragment visibility changes (the root cause trigger)
ShellSectionRendererhas direct access to_shellToolbarfield- Minimal code footprint (11 lines of actual logic)
- No refactoring of class hierarchy required
- Proper null checks (
_shellToolbar?.Handler != null) prevent edge case crashes
📋 Report — Final Recommendation
📝 Review Session — Added null check for handler · 7cb9cee
Status: ✅ COMPLETE
Final Recommendation: APPROVE
Root Cause Analysis
When switching tabs in Shell on Android, fragments are reused via HideEx()/ShowEx() calls in ShellItemRendererBase (lines 235-242). When a fragment becomes visible again through OnHiddenChanged, the TitleView handler's update isn't automatically triggered, leaving the TitleView invisible.
Key Findings
- Bug confirmed as regression - Worked in 9.0.120, broken in 9.0.30+
- Android-only issue - Fragment lifecycle specific to Android
- Fix location is optimal -
OnHiddenChangedinShellSectionRendereris the exact lifecycle hook needed - Code quality is good - Proper null checks, uses
nameof(), minimal footprint
Verdict
✅ APPROVE - This is a well-crafted fix that correctly addresses the regression. The approach is minimal, targeted, and uses proper Android lifecycle patterns.
Minor Issues
- Commented-out code in test file (Issue33304.cs line 13) should be removed before merge
🤖 Generated by Copilot CLI
| protected IShellContext ShellContext => _shellContext; | ||
| IShellSectionController SectionController => (IShellSectionController)ShellSection; | ||
| IMauiContext MauiContext => ShellContext.Shell.Handler.MauiContext; | ||
| Toolbar _shellToolbar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you set this to null inside Destroy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you set this to null inside Destroy?
I set _shellToolbar to null on Destroy method.
|
/rebase |
2f1b346 to
9eeed4d
Compare
Issue Details:
Shell TitleView disappears when switching between tabs on Android (regression from MAUI 9.0.30).
Root Cause:
When switching tabs, we reuses fragments by hiding/showing them if the ShellNavigationSource is ShellSectionChanged in ShellItemRendererBase class(line number 235 to 242). When a fragment becomes visible again, the TitleView handler update isn't automatically triggered, leaving the TitleView invisible.
Description of Change:
Updated TitleView of the shellToobar when fragment becomes visible after being hidden, ensuring TitleView appears when switching back to a tab.
Tested the behavior in the following platforms.
Reference:
N/A
Issues Fixed:
Fixes #33304
Screenshots
Screen.Recording.2026-01-12.at.11.31.08.AM.mov
Screen.Recording.2026-01-12.at.11.34.16.AM.mov