Skip to content

Conversation

@KarthikRajaKalaimani
Copy link
Contributor

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.

  • Android
  • Windows
  • iOS
  • Mac

Reference:

N/A

Issues Fixed:

Fixes #33304

Screenshots

Before After
Screen.Recording.2026-01-12.at.11.31.08.AM.mov
Screen.Recording.2026-01-12.at.11.34.16.AM.mov

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Jan 12, 2026
@dotnet-policy-service
Copy link
Contributor

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.

@dotnet-policy-service dotnet-policy-service bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Jan 12, 2026
@Tamilarasan-Paranthaman Tamilarasan-Paranthaman added platform/android area-controls-shell Shell Navigation, Routes, Tabs, Flyout labels Jan 12, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review January 16, 2026 14:05
Copilot AI review requested due to automatic review settings January 16, 2026 14:05
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 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 OnHiddenChanged override in ShellSectionRenderer to update TitleView when fragment becomes visible
  • Stored Toolbar reference 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)
Copy link

Copilot AI Jan 16, 2026

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).

Suggested change
if (!hidden)
if (!hidden && _shellToolbar?.Handler != null)

Copilot uses AI. Check for mistakes.

if (!hidden)
{
_shellToolbar.Handler.UpdateValue("TitleView");
Copy link

Copilot AI Jan 16, 2026

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)).

Copilot uses AI. Check for mistakes.
Text = "TitleView",
AutomationId = "HomeTitleView"
});
// Shell.SetFlyoutBehavior(FlyoutBehavior.Disabled);
Copy link

Copilot AI Jan 16, 2026

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.

Suggested change
// Shell.SetFlyoutBehavior(FlyoutBehavior.Disabled);

Copilot uses AI. Check for mistakes.
@kubaflo
Copy link
Contributor

kubaflo commented Jan 25, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionAdded null check for handler · 7cb9cee

Bug: On Android, a Shell.TitleView displays correctly on the first tab. When switching to the second tab, the TitleView disappears, even though it is defined in the Shell. Switching to a third tab causes the TitleView to render correctly again.

Steps to Reproduce:

  1. Create a new .NET MAUI app with Shell
  2. Define a Shell.TitleView in the Shell (e.g., a custom layout or label)
  3. Configure a TabBar with at least three tab items
  4. Build and run targeting Android
  5. Navigate between tabs - TitleView appears on first tab, disappears on second tab, reappears on third

Platforms Affected:

  • Android
  • iOS
  • Windows
  • MacCatalyst

Regression: Yes - regressed in MAUI 9.0.30

Root Cause (from PR): When switching tabs, fragments are reused by hiding/showing them (in ShellItemRendererBase, lines 235-242). When a fragment becomes visible again via OnHiddenChanged, the TitleView handler update isn't automatically triggered, leaving the TitleView invisible.


🧪 Tests — Verification
📝 Review SessionAdded null check for handler · 7cb9cee

Status: ✅ COMPLETE

  • PR includes UI tests
  • Tests reproduce the issue (verified to FAIL without fix)
  • Tests follow naming convention (Issue33304)

Test Files:

  • HostApp: src/Controls/tests/TestCases.HostApp/Issues/Issue33304.cs
  • NUnit: src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33304.cs

Test Logic:

  1. Wait for HomeTabLabel
  2. Tap Search tab
  3. Wait for SearchTabLabel
  4. Tap Home tab
  5. Wait for HomeTabLabel
  6. Verify HomeTitleView is visible (this fails without fix)

🚦 Gate — Test Verification
📝 Review SessionAdded null check for handler · 7cb9cee

Status: ✅ PASSED

  • Tests FAIL without fix (bug reproduced)
  • Tests PASS with fix

Result: PASSED ✅

Verification Details:

  • With fix: Issue33304Test passes in 6 seconds - HomeTitleView found immediately after switching back to Home tab
  • Without fix: Issue33304Test fails - Appium repeatedly polls for HomeTitleView (26+ attempts over 15 seconds) and times out because TitleView disappears
  • Platform tested: Android (emulator-5556)

🔧 Fix — Analysis & Comparison
📝 Review SessionAdded null check for handler · 7cb9cee

Status: ✅ COMPLETE

# 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 delayed UpdateTitleView() call when navigation source is ShellSectionChanged
  • Why it failed: OnShellNavigated fires before fragment visibility change completes. Even posting via _platformToolbar.Post() doesn't work because:
    1. Navigation events fire at navigation start, not at fragment visibility change
    2. A single Post() delays by only one message queue cycle - insufficient for fragment transition
    3. 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:

  1. It fires at the exact moment when fragment visibility changes (the root cause trigger)
  2. ShellSectionRenderer has direct access to _shellToolbar field
  3. Minimal code footprint (11 lines of actual logic)
  4. No refactoring of class hierarchy required
  5. Proper null checks (_shellToolbar?.Handler != null) prevent edge case crashes

📋 Report — Final Recommendation
📝 Review SessionAdded 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

  1. Bug confirmed as regression - Worked in 9.0.120, broken in 9.0.30+
  2. Android-only issue - Fragment lifecycle specific to Android
  3. Fix location is optimal - OnHiddenChanged in ShellSectionRenderer is the exact lifecycle hook needed
  4. 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

kubaflo
kubaflo previously approved these changes Jan 25, 2026
protected IShellContext ShellContext => _shellContext;
IShellSectionController SectionController => (IShellSectionController)ShellSection;
IMauiContext MauiContext => ShellContext.Shell.Handler.MauiContext;
Toolbar _shellToolbar;
Copy link
Member

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?

Copy link
Contributor Author

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.

@PureWeen
Copy link
Member

/rebase

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 community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] TitleView defined in Shell is lost when changing tabs

4 participants