[Android] Fix TabBar FlowDirection not updating dynamically#33091
[Android] Fix TabBar FlowDirection not updating dynamically#33091PureWeen merged 3 commits intodotnet:inflight/currentfrom
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 33091Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 33091" |
|
Hey there @@SubhikshaSf4851! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR fixes an issue where FlowDirection changes were not applied dynamically to the TabBar on Android when the flyout content had not been created yet. The fix ensures that flow direction updates are processed before checking if _flyoutContent is null in ShellFlyoutRenderer.cs.
Key Changes
- Moved FlowDirection handling logic before the early return check in
OnShellPropertyChanged - Added UI tests to verify the TabBar updates correctly when switching to RTL mode
- Changed null check pattern from
== nulltois nullfor consistency with modern C# style
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs | Fixed OnShellPropertyChanged to process FlowDirection updates before checking if _flyoutContent is null |
| src/Controls/tests/TestCases.HostApp/Issues/Issue32993.cs | Added HostApp test page demonstrating TabBar with RTL switching functionality |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32993.cs | Added automated UI test to verify TabBar updates correctly in RTL mode |
|
/rebase |
35d7dd3 to
71487dc
Compare
🤖 AI Summary📊 Expand Full Review🔍 Pre-Flight — Context & Validation📝 Review Session — Added Snapshots ·
|
| Category | File | Changes |
|---|---|---|
| Fix | src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs |
+8 -5 |
| Test (HostApp) | src/Controls/tests/TestCases.HostApp/Issues/Issue32993.cs |
+64 new |
| Test (Shared) | src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32993.cs |
+25 new |
| Snapshot (Android) | src/Controls/tests/TestCases.Android.Tests/snapshots/android/Issue32993TabBarUpdatesCorrectlyInRTLMode.png |
Binary |
| Snapshot (Windows) | src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/Issue32993TabBarUpdatesCorrectlyInRTLMode.png |
Binary |
PR Discussion Summary
Copilot Reviewer Comments:
- Platform directive inconsistency (Test file): Test is restricted to ANDROID and WINDOWS only (
#if ANDROID || WINDOWS), but issue affects iOS too. Comment references PR [iOS, macOS] Shell: Fix RTL flow direction for flyout, menu cells, tab bar, and Locked flyout position #32701 for iOS/Mac fix. - PlatformAffected mismatch (HostApp):
PlatformAffectedattribute specifies iOS and Android, but test includes WINDOWS in directive. PR description says tested on Windows.
PR Author Response:
- No response yet to reviewer comments
- PR includes
/rebasecommand from maintainer (PureWeen)
Edge Cases Verified
- TabBar updates correctly when FlowDirection changed from LTR to RTL
- Fix works when flyout content is null (initial state)
- Fix works when flyout content exists
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #33091 | Move FlowDirection handling before _flyoutContent null check in OnShellPropertyChanged |
✅ PASS (Gate) | ShellFlyoutRenderer.cs (+8 -5) |
Original PR - Android only |
🚦 Gate — Test Verification
📝 Review Session — Added Snapshots · 71487dc
Result: ✅ PASSED
Platform: android
Mode: Full Verification
Test Filter: Issue32993
Verification Results
- Tests FAIL without fix ✅ (as expected)
- Tests PASS with fix ✅ (as expected)
Test Details
Test: Issue32993TabBarUpdatesCorrectlyInRTLMode
Without Fix:
- Test detected the bug - TabBar did not update FlowDirection to RTL correctly
- Screenshot comparison failed as expected (visual regression detected)
With Fix:
- Test passed - TabBar correctly updates to RTL mode
- All assertions passed
Conclusion
✅ The tests correctly catch the bug and validate the fix. The PR's implementation successfully resolves issue #32993 on Android.
🔧 Fix — Analysis & Comparison
📝 Review Session — Added Snapshots · 71487dc
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-sonnet-4.5) | Override OnShellItemPropertyChanged in ShellItemRenderer, update BottomNavigationView + containers LayoutDirection | ✅ PASS | ShellItemRenderer.cs (+39), PublicAPI.Unshipped.txt (+1) | Works - adds protected virtual override |
| 2 | try-fix (claude-opus-4.6) | Subscribe to Shell.PropertyChanged in OnCreateView, update _outerLayout LayoutDirection | ✅ PASS | ShellItemRenderer.cs (+18) | Works - minimal changes, updates only _outerLayout |
| 3 | try-fix (gpt-5.2) | Subscribe to Shell.PropertyChanged, set LayoutDirection on all 3 views with RequestLayout/Invalidate | ✅ PASS | ShellItemRenderer.cs (+24) | Works - comprehensive with explicit invalidation |
| 4 | try-fix (gpt-5.2-codex) | Subscribe to Shell.PropertyChanged, set LayoutDirection on all 3 views | ✅ PASS | ShellItemRenderer.cs (+25) | Works - similar to #3 without explicit invalidation |
| 5 | try-fix (gemini-3-pro-preview) | Set LayoutDirection only on _bottomView | ❌ FAIL (2.92% visual diff) | ShellItemRenderer.cs (+19) | Insufficient - needs containers too |
| PR | PR #33091 | Move UpdateFlowDirection() before _flyoutContent null check in ShellFlyoutRenderer | ✅ PASS (Gate) | ShellFlyoutRenderer.cs (+8 -5) | Original PR - fixes flyout renderer |
Cross-Pollination Results
Round 2 Responses:
| Model | Response | New Idea? |
|---|---|---|
| claude-sonnet-4.5 | Override OnAttachedToWindow to apply LayoutDirection at window attachment | Yes |
| claude-opus-4.6 | Override OnConfigurationChanged in ShellRenderer, propagate from root | Yes |
| gpt-5.2 | Recreate BottomNavigationView entirely instead of in-place update | Yes |
| gpt-5.2-codex | Override OnRtlPropertiesChanged, use ViewCompat.SetLayoutDirection | Yes |
| gemini-3-pro-preview | Override OnStart lifecycle to apply when view becomes visible | Yes |
Exhausted: Yes - All 5 models provided Round 2 ideas (incremental variations), core problem solved multiple times.
Selected Fix: PR's fix
Reasoning: While 4 try-fix attempts successfully solved the problem via ShellItemRenderer, the PR's fix in ShellFlyoutRenderer is superior:
- Addresses root cause - fixes the early return that blocked FlowDirection updates
- Minimal changes - 8 lines modified vs 18-39 new lines for alternatives
- Broader scope - affects TabBar AND any other flyout use cases
- No duplication - maintains single source of truth for FlowDirection handling in existing
UpdateFlowDirection()method - Consistent - keeps all FlowDirection handling centralized in
ShellFlyoutRendererwhere it already exists
📋 Report — Final Recommendation
📝 Review Session — Added Snapshots · 71487dc
✅ Final Recommendation: APPROVE
Summary
PR #33091 successfully fixes the Shell TabBar FlowDirection RTL update bug on Android. The fix is minimal, correct, and addresses the root cause. While the try-fix phase discovered 4 working alternatives that modify ShellItemRenderer, the PR's approach of fixing ShellFlyoutRenderer is superior due to simplicity, broader scope, and proper root cause resolution.
Root Cause
When Shell.FlowDirection is changed at runtime in a TabBar application, the ShellFlyoutRenderer.OnShellPropertyChanged method would return early if _flyoutContent was null, preventing the UpdateFlowDirection() call from executing. For TabBar-only applications, the flyout content may never be created, causing FlowDirection updates to be permanently ignored.
Key insight: The early return check was meant to guard flyout-specific operations, but FlowDirection updates should apply to ALL Shell components regardless of flyout state.
Fix Quality
PR's Approach (Selected):
- Moves
FlowDirectioncheck before the_flyoutContentnull check - Minimal changes: 8 lines modified (+8 -5)
- Reuses existing
UpdateFlowDirection()infrastructure - Fixes not just TabBar but all Shell components affected by the early return
- Maintains single source of truth for FlowDirection handling
Try-Fix Alternatives (Not Selected):
- 4 passing alternatives found (attempts 1-4), all modifying
ShellItemRenderer - These work by subscribing to
Shell.PropertyChangedand updating TabBar views directly - Add 18-39 lines of new code each
- Create duplication with existing FlowDirection logic in
ShellFlyoutRenderer - While functional, represent workarounds rather than root cause fixes
Platform Comparison
| Platform | Status | Notes |
|---|---|---|
| Android | ✅ Tested | Primary fix target, verified with Gate tests |
| Windows | ✅ Tested | Snapshot included in PR |
| iOS/Mac | 📋 Separate PR | Covered by PR #32701 per test file comment |
Test Coverage
- ✅ UI test:
Issue32993TabBarUpdatesCorrectlyInRTLMode - ✅ Test page:
Issue32993.cswith button to toggle RTL - ✅ Visual snapshots: Android and Windows
- ✅ Gate verification: Tests FAIL without fix, PASS with fix
Code Quality
Positive:
- Surgical fix with minimal changes
- Uses modern C# pattern (
is nullvs== null) - Proper scoping with braces
- Comprehensive testing
Minor Suggestions (non-blocking):
- Consider adding a code comment explaining why FlowDirection must be checked before the flyout null check
- PR title could be refined: "[Android] Shell TabBar: Update FlowDirection dynamically"
Architecture Impact
- No breaking changes
- No performance impact
- Proper separation of concerns maintained
- Centralized FlowDirection handling preserved
Verdict
The PR correctly addresses issue #32993. The implementation is clean, well-tested, and superior to alternative approaches explored in try-fix phase.
Approve and merge.
📋 Expand PR Finalization Review
Title: ✅ Good
Current: [Android] Fixed TabBar should update FlowDirection dynamically
Description: ✅ Good
- "Fixed" should be "Fix" — PR titles become commit messages and should use imperative mood (standard git convention)
- "should update" is a description of the desired state, not what changed — slightly awkward phrasing
✨ Suggested PR Description
[!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
In ShellFlyoutRenderer.OnShellPropertyChanged, there was an early return when _flyoutContent == null. For Shell apps using a TabBar (no flyout), _flyoutContent is always null because no flyout content is ever created. This meant FlowDirection property changes were silently dropped at runtime — the UpdateFlowDirection() call in the else if branch was never reached.
Description of Change
Moved the FlowDirection check to execute before the _flyoutContent == null early return in ShellFlyoutRenderer.OnShellPropertyChanged. This ensures UpdateFlowDirection() is always called when Shell.FlowDirectionProperty changes, regardless of whether flyout content has been created.
The remaining early return for _flyoutContent == null is preserved so that flyout-specific property handling (e.g., FlyoutIsPresentedProperty) is still guarded correctly.
Affected file: src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cs
Note on iOS/Mac: The same symptom on iOS/Mac is tracked in PR #32701, which addresses the iOS-side TabBar FlowDirection handling. This PR is Android-only.
Note on Windows test: A Windows test snapshot is included because the UI test (Issue32993.cs) runs on both Android and Windows (#if ANDROID || WINDOWS). The Windows fix was already working; the snapshot captures the expected behavior for regression testing.
Issues Fixed
Fixes #32993
Platforms Tested
- Android ✅ (fix applies here)
- iOS (tracked in PR [iOS, macOS] Shell: Fix RTL flow direction for flyout, menu cells, tab bar, and Locked flyout position #32701)
- Mac (tracked in PR [iOS, macOS] Shell: Fix RTL flow direction for flyout, menu cells, tab bar, and Locked flyout position #32701)
- Windows ✅ (test captures expected behavior; no code change needed)
Code Review: ✅ Passed
Code Review — PR #33091
✅ Core Fix: ShellFlyoutRenderer.cs
The logic change in OnShellPropertyChanged is correct and minimal.
Before:
if (_flyoutContent == null)
return;
if (e.PropertyName == Shell.FlyoutIsPresentedProperty.PropertyName)
{ ... }
else if (e.PropertyName == Shell.FlowDirectionProperty.PropertyName)
{ UpdateFlowDirection(); }After:
if (e.PropertyName == Shell.FlowDirectionProperty.PropertyName)
{
UpdateFlowDirection();
}
if (_flyoutContent is null)
{
return;
}
if (e.PropertyName == Shell.FlyoutIsPresentedProperty.PropertyName)
{ ... }- ✅
FlowDirectionupdate is now unconditional — correct, since it doesn't depend on flyout content - ✅ Uses
is nullpattern (idiomatic C#) for the revised null check, consistent with modern C# style - ✅ All other flyout-dependent checks remain correctly guarded by the
_flyoutContent is nullreturn - ✅ No risk of double-calling
UpdateFlowDirection()— the oldelse ifbranch is removed
🟡 Suggestions
1. Test file: Missing newline at end of file
Both Issue32993.cs test files (HostApp and Shared.Tests) are missing a newline at the end of file (\\ No newline at end of file in the diff). This is a minor but common style issue.
Files:
src/Controls/tests/TestCases.HostApp/Issues/Issue32993.cssrc/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32993.cs
2. Test: VerifyScreenshot without retryTimeout
The test taps a button that triggers a FlowDirection property change, which may involve layout/animation. Using VerifyScreenshot() without a retryTimeout could cause flaky failures if the layout hasn't settled.
File: src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32993.cs
// Current:
VerifyScreenshot();
// Suggested (more robust):
VerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2));3. PlatformAffected inconsistency in HostApp (already flagged, resolved)
The [Issue] attribute in Issue32993.cs (HostApp) specifies PlatformAffected.iOS | PlatformAffected.Android but the test runs on Windows too (per #if ANDROID || WINDOWS). The Copilot reviewer already flagged this and it was resolved; verify the final state includes PlatformAffected.Windows.
4. Test platforms scoping comment
The #if ANDROID || WINDOWS comment explains iOS/Mac are excluded due to PR #32701. This is acceptable at a file level but the comment text could be more precise:
// Current:
#if ANDROID || WINDOWS //Existing PR for iOS and mac which resolve the FlowDirection issue on TabBar https://github.com/dotnet/maui/pull/32701
// Clearer:
#if ANDROID || WINDOWS // iOS/Mac have a separate fix in PR #32701; enable this test there once merged✅ Looks Good
- Fix is surgical — only 13 lines changed in the core fix file
- Test correctly reproduces the issue: starts LTR, taps button to switch to RTL, verifies via screenshot
- Windows snapshot included for regression coverage
- Two resolved Copilot review comments show the PR was already reviewed and improvements were incorporated
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
…3091) <!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes dotnet#32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root cause: `FlowDirection` changes were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar. ### Description of Change : Updated `OnShellPropertyChanged` in `ShellFlyoutRenderer.cs` to always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #32993 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/9eafa422-53a8-449b-ba15-6462d16353d4"> | <video src="https://github.com/user-attachments/assets/5a20cc1d-abf5-4f5c-b0d6-5a8b5512e517"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
## What's Coming .NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 46 commits with various improvements, bug fixes, and enhancements. ## Button - [Android] Implemented material3 support for Button by @Dhivya-SF4094 in #33173 <details> <summary>🔧 Fixes</summary> - [Implement Material3 support for Button](#33172) </details> ## CollectionView - [Android] Fix RemainingItemsThresholdReachedCommand not firing when CollectionView has Header and Footer both defined by @SuthiYuvaraj in #29618 <details> <summary>🔧 Fixes</summary> - [Android : RemainingItemsThresholdReachedCommand not firing when CollectionVew has Header and Footer both defined](#29588) </details> - [iOS/MacCatalyst] Fix CollectionView ScrollTo for horizontal layouts by @Shalini-Ashokan in #33853 <details> <summary>🔧 Fixes</summary> - [[iOS/MacCatalyst] CollectionView ScrollTo does not work with horizontal Layout](#33852) </details> - [iOS & Mac] Fixed IndicatorView Size doesnt update dynamically by @SubhikshaSf4851 in #31129 <details> <summary>🔧 Fixes</summary> - [[iOS, Catalyst] IndicatorView.IndicatorSize does not update dynamically at runtime](#31064) </details> - [Android] Fix for CollectionView Scrolled event is triggered on the initial app load. by @BagavathiPerumal in #33558 <details> <summary>🔧 Fixes</summary> - [[Android] CollectionView Scrolled event is triggered on the initial app load.](#33333) </details> - [iOS, Android] Fix for CollectionView IsEnabled=false allows touch interactions by @praveenkumarkarunanithi in #31403 <details> <summary>🔧 Fixes</summary> - [More issues with CollectionView IsEnabled, InputTransparent, Opacity via Styles and code behind](#19771) </details> - [iOS] Fix VerticalOffset Update When Modifying CollectionView.ItemsSource While Scrolled by @devanathan-vaithiyanathan in #34153 <details> <summary>🔧 Fixes</summary> - [[iOS]VerticalOffset Not Reset to Zero After Clearing ItemSource in CollectionView](#26798) </details> ## DateTimePicker - [Android] Fix DatePicker MinimumDate/MaximumDate not updating dynamically by @HarishwaranVijayakumar in #33687 <details> <summary>🔧 Fixes</summary> - [[regression/8.0.3] [Android] DatePicker control minimum date issue](#19256) - [[Android] DatePicker does not update MinimumDate / MaximumDate in the Popup when set in the viewmodel after first opening](#33583) </details> ## Drawing - Android drawable perf by @albyrock87 in #31567 ## Editor - [Android] Implemented material3 support for Editor by @SyedAbdulAzeemSF4852 in #33478 <details> <summary>🔧 Fixes</summary> - [Implement Material3 Support for Editor](#33476) </details> ## Entry - [iOS, Mac] Fix for CursorPosition not updating when typing into Entry control by @SyedAbdulAzeemSF4852 in #30505 <details> <summary>🔧 Fixes</summary> - [Entry control CursorPosition does not update on TextChanged event [iOS Maui 8.0.7] ](#20911) - [CursorPosition not calculated correctly on behaviors events for iOS devices](#32483) </details> ## Flyoutpage - [Android, Windows] Fix for FlyoutPage toolbar button not updating on orientation change by @praveenkumarkarunanithi in #31962 <details> <summary>🔧 Fixes</summary> - [Flyout page in Android does not show flyout button (burger) consistently](#24468) </details> - Fix for First Item in CollectionView Overlaps in FlyoutPage.Flyout on iOS by @praveenkumarkarunanithi in #29265 <details> <summary>🔧 Fixes</summary> - [[iOS] CollectionView not rendering first item correctly in FlyoutPage.Flyout](#29170) </details> ## Image - [Android] Fix excessive memory usage for stream and resource-based image loading by @Shalini-Ashokan in #33590 <details> <summary>🔧 Fixes</summary> - [[Android] Unexpected high Bitmap.ByteCount when loading image via ImageSource.FromResource() or ImageSource.FromStream() in .NET MAUI](#33239) </details> - [Android] Fix for Resize method returns an image that has already been disposed by @SyedAbdulAzeemSF4852 in #29964 <details> <summary>🔧 Fixes</summary> - [In GraphicsView, the Resize method returns an image that has already been disposed](#29961) - [IIMage.Resize bugged behaviour](#31103) </details> ## Label - Fixed Label Span font property inheritance when applied via Style by @SubhikshaSf4851 in #34110 <details> <summary>🔧 Fixes</summary> - [`Span` does not inherit text styling from `Label` if that styling is applied using `Style` ](#21326) </details> - [Android] Implemented material3 support for Label by @SyedAbdulAzeemSF4852 in #33599 <details> <summary>🔧 Fixes</summary> - [Implement Material3 Support for Label](#33598) </details> ## Map - [Android] Fix Circle Stroke color is incorrectly updated as Fill color. by @NirmalKumarYuvaraj in #33643 <details> <summary>🔧 Fixes</summary> - [[Android] Circle Stroke color is incorrectly updated as Fill color.](#33642) </details> ## Mediapicker - [iOS] Fix: invoke MediaPicker completion handler after DismissViewController by @yuriikyry4enko in #34250 <details> <summary>🔧 Fixes</summary> - [[iOS] Media Picker UIImagePickerController closing issue](#21996) </details> ## Navigation - Fix ContentPage memory leak on Android when using NavigationPage modally (fixes #33918) by @brunck in #34117 <details> <summary>🔧 Fixes</summary> - [[Android] Modal TabbedPage whose tabs are NavigationPage(ContentPage) is retained after PopModalAsync()](#33918) </details> ## Picker - [Android] Implement material3 support for TimePicker by @HarishwaranVijayakumar in #33646 <details> <summary>🔧 Fixes</summary> - [Implement Material3 support for TimePicker](#33645) </details> - [Android] Implemented Material3 support for Picker by @SyedAbdulAzeemSF4852 in #33668 <details> <summary>🔧 Fixes</summary> - [Implement Material3 support for Picker](#33665) </details> ## RadioButton - [Android] Implemented material3 support for RadioButton by @SyedAbdulAzeemSF4852 in #33468 <details> <summary>🔧 Fixes</summary> - [Implement Material3 Support for RadioButton](#33467) </details> ## Setup - Clarify MA003 error message by @jeremy-visionaid in #34067 <details> <summary>🔧 Fixes</summary> - [MA003 false positive with 9.0.21](#26599) </details> ## Shell - [Android] Fix TabBar FlowDirection not updating dynamically by @SubhikshaSf4851 in #33091 <details> <summary>🔧 Fixes</summary> - [[Android, iOS] FlowDirection RTL is not updated dynamically on Shell TabBar](#32993) </details> - [Android] Fix page not disposed on Shell replace navigation by @Vignesh-SF3580 in #33426 <details> <summary>🔧 Fixes</summary> - [[Android] [Shell] replace navigation leaks current page](#25134) </details> - [Android] Fixed Shell flyout does not disable scrolling when FlyoutVerticalScrollMode is set to Disabled by @NanthiniMahalingam in #32734 <details> <summary>🔧 Fixes</summary> - [[Android] Shell.FlyoutVerticalScrollMode="Disabled" does not disable scrolling](#32477) </details> ## Single Project - Fix: Throw a clear error when an SVG lacks dimensions instead of a NullReferenceException by @Shalini-Ashokan in #33194 <details> <summary>🔧 Fixes</summary> - [MAUI Fails To Convert Valid SVG Files Into PNG Files (Object reference not set to an instance of an object)](#32460) </details> ## SwipeView - [iOS] Fix SwipeView stays open on iOS after updating content by @devanathan-vaithiyanathan in #31248 <details> <summary>🔧 Fixes</summary> - [[iOS] - Swipeview with collectionview issue](#19541) </details> ## TabbedPage - [Windows] Fixed IsEnabled Property not works on Tabs by @NirmalKumarYuvaraj in #26728 <details> <summary>🔧 Fixes</summary> - [ShellContent IsEnabledProperty does not work](#5161) - [[Windows] Shell Tab IsEnabled Not Working](#32996) </details> - [Android] Fix NavigationBar overlapping StatusBar when NavigationBar visibility changes by @Vignesh-SF3580 in #33359 <details> <summary>🔧 Fixes</summary> - [[Android] NavigationBar overlaps with StatusBar when mixing HasNavigationBar=true/false in TabbedPage on Android 15 (API 35)](#33340) </details> ## Templates - Fix for unable to open task using keyboard navigation on windows platform by @SuthiYuvaraj in #33647 <details> <summary>🔧 Fixes</summary> - [Unable to open task using keyboard: A11y_.NET maui_User can get all the insights of Dashboard_Keyboard](#30787) </details> ## TitleView - Fix for NavigationPage.TitleView does not expand with host window in iPadOS 26+ by @SuthiYuvaraj in #33088 ## Toolbar - [iOS] Fix toolbar items ignoring BarTextColor on iOS/MacCatalyst 26+ by @Shalini-Ashokan in #34036 <details> <summary>🔧 Fixes</summary> - [[iOS 26] ToolbarItem color with custom BarTextColor not working](#33970) </details> - [Android] Fix for ToolbarItem retaining the icon from the previous page on Android when using NavigationPage. by @BagavathiPerumal in #32311 <details> <summary>🔧 Fixes</summary> - [Toolbaritem keeps the icon of the previous page on Android, using NavigationPage (not shell)](#31727) </details> ## WebView - [Android] Fix WebView in a grid expands beyond it's cell by @devanathan-vaithiyanathan in #32145 <details> <summary>🔧 Fixes</summary> - [Android - WebView in a grid expands beyond it's cell](#32030) </details> ## Xaml - ContentPresenter: Propagate binding context to children with explicit TemplateBinding by @HarishwaranVijayakumar in #30880 <details> <summary>🔧 Fixes</summary> - [Binding context in ContentPresenter](#23797) </details> <details> <summary>🔧 Infrastructure (1)</summary> - [Revert] ContentPresenter: Propagate binding context to children with explicit TemplateBinding by @Ahamed-Ali in #34332 </details> <details> <summary>🧪 Testing (6)</summary> - [Testing] Feature Matrix UITest Cases for Shell Flyout Page by @NafeelaNazhir in #32525 - [Testing] Feature Matrix UITest Cases for Brushes by @LogishaSelvarajSF4525 in #31833 - [Testing] Feature Matrix UITest Cases for BindableLayout by @LogishaSelvarajSF4525 in #33108 - [Android] Add UI tests for Material 3 CheckBox by @HarishwaranVijayakumar in #34126 <details> <summary>🔧 Fixes</summary> - [[Android] Add UI tests for Material 3 CheckBox](#34125) </details> - [Testing] Feature Matrix UITest Cases for Shell Tabbed Page by @NafeelaNazhir in #33159 - [Testing] Fixed Test case failure in PR 34294 - [03/2/2026] Candidate - 1 by @TamilarasanSF4853 in #34334 </details> <details> <summary>📦 Other (2)</summary> - Bumps Syncfusion.Maui.Toolkit dependency to version 1.0.9 by @PaulAndersonS in #34178 - Fix crash when closing Windows based app when using TitleBar by @MFinkBK in #34032 <details> <summary>🔧 Fixes</summary> - [Unhandled exception "Value does not fall within the expected range" when closing Windows app](#32194) </details> </details> **Full Changelog**: main...inflight/candidate
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:
FlowDirectionchanges were not applied when _flyoutContent was null. Because the method returned early, the FlowDirection update logic did not executed on dynamic updates. But this check is not required for tabbar.Description of Change :
Updated
OnShellPropertyChangedinShellFlyoutRenderer.csto always process FlowDirection changes before checking _flyoutContent, ensuring flow direction updates apply correctly even when the flyout has not yet been created.Issues Fixed
Fixes #32993
Tested the behavior in the following platforms
Screen.Recording.2025-12-10.at.17.49.02.mov
Screen.Recording.2025-12-10.at.17.47.17.mov