Skip to content

[Android] Fix control size properties not available during Loaded event#31590

Merged
kubaflo merged 5 commits intodotnet:inflight/currentfrom
Vignesh-SF3580:fix-14364
Mar 10, 2026
Merged

[Android] Fix control size properties not available during Loaded event#31590
kubaflo merged 5 commits intodotnet:inflight/currentfrom
Vignesh-SF3580:fix-14364

Conversation

@Vignesh-SF3580
Copy link
Copy Markdown
Contributor

@Vignesh-SF3580 Vignesh-SF3580 commented Sep 12, 2025

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!

Issue Details

On Android, controls do not provide valid size when the Loaded event fires.



Root Cause

On Android, the Loaded event fires before the layout pass completes, causing views to report incorrect dimensions.

Description of Change

Modified OnLoaded method to use view.Post() instead of immediate action execution, ensuring the Loaded event fires after the layout pass completes.

Tested the behavior in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Issues Fixed

Fixes #14364
Fixes #14160

Screenshots

Before Issue Fix After Issue Fix
image image

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Sep 12, 2025
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@Vignesh-SF3580! 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 Sep 12, 2025
@jsuarezruiz
Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@Vignesh-SF3580 Vignesh-SF3580 marked this pull request as ready for review September 18, 2025 10:28
Copilot AI review requested due to automatic review settings September 18, 2025 10:28
Copy link
Copy Markdown
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 control size properties (Height and Width) were not available during the Loaded event because the event fired before the layout pass completed.

  • Modified the OnLoaded method to use view.Post() to defer action execution until after layout completion
  • Added comprehensive UI tests to validate the fix works correctly
  • Ensures size properties are properly available when Loaded event handlers execute

Reviewed Changes

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

File Description
src/Core/src/Platform/Android/ViewExtensions.cs Changed immediate action execution to deferred execution using view.Post()
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue14364.cs Added NUnit test to verify size properties are available during Loaded event
src/Controls/tests/TestCases.HostApp/Issues/Issue14364.cs Added test page with Grid and Label to reproduce and validate the issue fix

@jsuarezruiz
Copy link
Copy Markdown
Contributor

/rebase

@jsuarezruiz
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 9, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 31590

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 31590"

@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 18, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionUpdate ViewExtensions.cs · 58db172

Issue: #14364 - CollectionView on Android does not provide height/width/size during Loaded event
PR: #31590 - [Android] Fix control size properties not available during Loaded event
Platforms Affected: Android only (platform/android label)
Files Changed: 1 implementation file, 2 test files
Author: Vignesh-SF3580 (Syncfusion partner, community contribution)
Current Commit: 58db172
Prior Agent Reviews: Yes - prior reviews on older commits (bddc900); labels s/agent-reviewed, s/agent-approved, s/agent-fix-pr-picked already applied

Issue Summary

On Android, the Loaded event fires before the layout pass completes, causing controls (Labels, CollectionViews, etc.) to report incorrect dimensions (Height: -1, Width: -1). This works correctly on Windows and iOS where the layout pass completes before Loaded fires. Issues #14364 and #14160 both describe the same root cause.

Fix Approach (Current Commit: 58db172)

In src/Core/src/Platform/Android/ViewExtensions.cs, the OnLoaded method's ViewAttachedToWindow event handler now uses view.Post() to defer execution to after the current layout pass. Key improvements over prior commits:

  • localDisposable captures reference before nulling field, preventing race conditions
  • Disposal happens INSIDE the Post callback, AFTER calling action() (correct lifecycle)
  • IsAttachedToWindow guard prevents action from firing if view was detached
  • localDisposable is not null guard prevents double-execution

Current code:

var localDisposable = disposable;
disposable = null;
view.Post(() =>
{
    if (view.IsAttachedToWindow && localDisposable is not null)
    {
        action();
        localDisposable.Dispose();
    }
});

PR Discussion Summary

  • jsuarezruiz (reviewer) requested changes: add IsAttachedToWindow guard since action runs asynchronously
  • Author updated code, adding localDisposable pattern + IsAttachedToWindow check
  • copilot-pull-request-reviewer found no issues with changed files
  • Prior agent reviews (on bddc900) confirmed Gate PASSED and recommended APPROVE

Key Reviewer Feedback

File:Line Reviewer Feedback Status
ViewExtensions.cs:583 jsuarezruiz Add IsAttachedToWindow guard inside Post callback ✅ Implemented

Edge Cases

  • View detached between ViewAttachedToWindow and Post() — handled by IsAttachedToWindow check
  • Disposal race — mitigated by localDisposable pattern (local reference before nulling field)
  • Action called after disposal — prevented by localDisposable is not null check + disposal after action()
  • Loaded fires twice — guarded by localDisposable is not null

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31590 view.Post() with IsAttachedToWindow + localDisposable pattern ⏳ PENDING (Gate) ViewExtensions.cs (+10/-2) Current commit 58db172

🚦 Gate — Test Verification
📝 Review SessionUpdate ViewExtensions.cs · 58db172

Result: ✅ PASSED
Platform: android
Mode: Full Verification

  • Tests FAIL without fix ✅
  • Tests PASS with fix ✅
Check Expected Actual Result
Tests WITHOUT fix FAIL FAIL
Tests WITH fix PASS PASS

Test: Issue14364.SizePropertiesAvailableDuringLoadedEvent
Conclusion: The tests properly validate the fix and catch the bug when it's present.

Platform Note: Android is the affected platform per the platform/android label and the fix in Platform/Android/ViewExtensions.cs. Testing on an unaffected platform would yield false positives.


🔧 Fix — Analysis & Comparison
📝 Review SessionUpdate ViewExtensions.cs · 58db172

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #31590 view.Post() with IsAttachedToWindow + localDisposable ✅ PASS (Gate) 1 file (+10/-2) Simplest, most idiomatic Android pattern
1 try-fix (claude-sonnet-4.6) ViewTreeObserver.IOnGlobalLayoutListener ✅ PASS 1 file (+71/-2) Works but fires tree-wide, adds helper class
2 try-fix (claude-opus-4.6) view.LayoutChange event (per-view listener) ✅ PASS 1 file (+14/-2) Works, semantically precise, but adds event subscription complexity
3 try-fix (gpt-5.2) Choreographer.IFrameCallback with IsLaidOut/dimension polling ✅ PASS 1 file (large) Works but significantly more complex, adds polling class
4 try-fix (gpt-5.3-codex) Handler(Looper.MainLooper) + PostDelayed readiness loop ✅ PASS 1 file (+45/-15) Works but adds retry logic and timing delays
5 try-fix (gemini-3-pro-preview) ViewTreeObserver.IOnPreDrawListener ✅ PASS 1 file (+35/-17) Works but adds helper class, fires before every draw

Cross-Pollination Summary

Round Model Response
2 claude-sonnet-4.6 NO NEW IDEAS
2 claude-opus-4.6 NO NEW IDEAS
2 gpt-5.2 NO NEW IDEAS
2 gpt-5.3-codex NO NEW IDEAS
2 gemini-3-pro-preview NO NEW IDEAS

Exhausted: Yes — all 5 models confirmed no new ideas in Round 2. The fix space spans all practical Android layout-readiness mechanisms: message queue deferral, layout lifecycle callbacks, and frame pipeline hooks.

Selected Fix: PR's fix — view.Post() with IsAttachedToWindow guard and localDisposable pattern. All 5 alternatives also pass, but the PR's approach is:

  • Fewest lines changed (+10/-2 vs +14 to +71 for alternatives)
  • Most idiomatic Android pattern (view.Post() is the canonical deferral mechanism)
  • No helper classes needed
  • Easiest to understand and maintain

📋 Report — Final Recommendation
📝 Review SessionUpdate ViewExtensions.cs · 58db172

✅ Final Recommendation: APPROVE


PR Finalize Analysis

✅ Title: Good — No Change Needed

Current: [Android] Fix control size properties not available during Loaded event

The title is accurate, has the correct platform prefix, describes the behavior being fixed, and is searchable. No change recommended.

✅ Description: Good — Minor Enhancement Suggested

Quality assessment:

Suggested addition to "Description of Change" section:

Key detail: view.Post() queues execution for the next Looper cycle (after the layout pass), ensuring Width and Height are valid when the Loaded handler fires. The localDisposable pattern captures the reference before nulling the field so disposal can happen correctly inside the callback, after calling action(). The IsAttachedToWindow guard prevents action from firing if the view was detached between ViewAttachedToWindow and post execution.

What NOT to Do (for future agents)

  • Don't use ViewTreeObserver.IOnGlobalLayoutListener — Works but fires tree-wide after any view layout, more verbose, requires a helper class
  • Don't use view.LayoutChange event — Works but adds per-view listener lifecycle complexity for the same outcome
  • Don't use Choreographer.IFrameCallback — Works but significantly more complex, adds polling class with retry logic
  • Don't use Handler(Looper.MainLooper) + PostDelayed — Works but introduces timing delays and retry logic (45+ lines vs 10)
  • Don't use ViewTreeObserver.IOnPreDrawListener — Works but adds helper class and fires before every draw frame

Code Review Findings

✅ Looks Good

  • Minimal change: Only 10 lines changed in the fix file — the smallest change that correctly fixes the root cause
  • Idiomatic Android pattern: view.Post() is the canonical Android idiom for deferring work to after the current layout pass; confirmed by 5 independent model explorations
  • localDisposable pattern is correct: Captures local reference before nulling field, disposes inside callback after calling action() — correct lifecycle ordering
  • IsAttachedToWindow guard: Addresses reviewer feedback from jsuarezruiz; prevents stale action execution if view detaches between event and callback
  • localDisposable is not null guard: Prevents double-execution if somehow invoked twice
  • Test assertions: Is.Not.EqualTo("Height: -1, Width: -1") correctly validates the broken state without hardcoding specific pixel values (fragile)
  • [Category(UITestCategories.Layout)]: Appropriate category for a layout timing test
  • Both issues fixed: CollectionView on Android does not provide height, width, logical children once loaded, works fine on Windows #14364 and Control's Loaded event invokes before calling its measure override method. #14160 describe the same root cause; one fix/test covers both

🟡 Minor Observations

  1. Missing newline at end of TestCases.Shared.Tests/Tests/Issues/Issue14364.cs (\ No newline at end of file in diff). Minor style issue.

  2. Issue14364 HostApp extends Shell directly instead of TestShell. Per UITest guidelines TestShell is preferred for Shell tests; however this implementation is functionally correct and the custom Shell setup is minimal and clear.

  3. Test asserts negative (Not.EqualTo) rather than positive dimensions. This is appropriate for a regression test — asserting the bug state is gone without fragile pixel value assertions. Optional enhancement: add Assert.That(double.Parse(...), Is.GreaterThan(0)).

🔴 No Critical Issues Found


Summary of Findings

Phase Completion Status

Phase Status Notes
✅ Pre-Flight Complete PR context gathered, current commit 58db172 reviewed
✅ Gate PASSED Tests FAIL without fix, PASS with fix (Android)
✅ Fix Complete 5 alternatives explored (all pass), PR's fix is simplest
✅ Report Complete This document

Fix Validation Summary

# Source Approach Test Result
PR PR #31590 view.Post() + IsAttachedToWindow + localDisposable ✅ PASS (Gate verified)
1 try-fix ViewTreeObserver.IOnGlobalLayoutListener ✅ PASS
2 try-fix view.LayoutChange event ✅ PASS
3 try-fix Choreographer.IFrameCallback with dimension polling ✅ PASS
4 try-fix Handler(Looper.MainLooper) + PostDelayed retry loop ✅ PASS
5 try-fix ViewTreeObserver.IOnPreDrawListener ✅ PASS

Cross-pollination: Round 2 with all 5 models — unanimous "NO NEW IDEAS". Fix space exhausted.

Selected Fix: PR's fix — all 5 alternatives also pass, but view.Post() is the simplest, most idiomatic Android pattern with the fewest lines changed.

Final Recommendation

APPROVE — The PR correctly fixes a real Android-specific timing bug:

  • Root cause confirmed: ViewAttachedToWindow fires before the layout pass completes on Android
  • Fix is correct and idiomatic: view.Post() defers to the next Looper cycle (after layout)
  • Guards are appropriate: IsAttachedToWindow + localDisposable is not null
  • Reviewer feedback from jsuarezruiz has been fully incorporated
  • Tests properly validate the fix
  • Five independently-generated alternatives all confirm the approach space is well-covered
  • PR's implementation is the simplest of all valid alternatives

📋 Expand PR Finalization Review
Title: ✅ Good

Current: [Android] Fix control size properties not available during Loaded event

Description: ✅ Good

Description needs updates. See details below.

✨ 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

On Android, the ViewAttachedToWindow event fires as soon as the view is attached to the window hierarchy, but before Android's layout pass completes. This means that at the moment the MAUI Loaded event was fired, Height, Width, DesiredSize, and LogicalChildren all reported stale/default values (e.g., -1 for dimensions).

Description of Change

Modified the routedEventHandler lambda inside OnLoaded in src/Core/src/Platform/Android/ViewExtensions.cs to defer the action via view.Post() instead of calling it immediately inline.

view.Post() enqueues work on Android's main message queue, so it runs after the current layout pass has completed. By the time the posted callback fires, all dimension properties are populated.

Key implementation detail: The existing disposable reference is captured into a localDisposable local variable before posting, then set to null. This allows the async callback to safely check whether the subscription was cancelled between the event firing and the callback running.

What changed and what didn't:

  • ✅ Changed: The "normal" path in routedEventHandler — where the view becomes attached and is already considered loaded — now defers via view.Post()
  • ✅ Unchanged: The "fast path" where OnLoaded is called on an already-loaded view (immediate call is still correct there; layout has already completed)
  • ✅ Unchanged: The !view.IsLoaded() retry path that already used new Handler(q).Post()

What NOT to Do (for future agents)

  • Don't call action() directly in ViewAttachedToWindow — Android fires this event before the layout pass completes; dimensions will be -1 or stale
  • Don't skip the localDisposable pattern — Without capturing disposable locally before the async callback, setting disposable = null would race with any caller trying to cancel the subscription

Issues Fixed

Fixes #14364
Fixes #14160

Tested the behavior in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Screenshots

Before Issue Fix After Issue Fix
image image
Code Review: ✅ Passed

Code Review — PR #31590

File changed: src/Core/src/Platform/Android/ViewExtensions.cs
Test files added: Issue14364.cs (HostApp + SharedTests)


🟡 Suggestions

1. localDisposable is not disposed when view detaches before the Post callback runs

File: src/Core/src/Platform/Android/ViewExtensions.cs (lines ~644–653)

Problem: The new code sets disposable = null and enqueues a view.Post() callback. Inside that callback, if view.IsAttachedToWindow is false (the view detached between the event firing and the callback running), neither action() is called nor localDisposable.Dispose() is invoked. localDisposable.Dispose() is what unsubscribes routedEventHandler from view.ViewAttachedToWindow. As a result, the event handler remains subscribed on the view.

If the view is later re-attached, routedEventHandler will fire a second time. At that point, disposable is null (it was set to null in the first invocation), so localDisposable = disposable captures null, and the action is skipped — this prevents a double-fire. However, the handler is never cleaned up, creating a long-lived unnecessary reference.

Code (current):

var localDisposable = disposable;
disposable = null;
view.Post(() =>
{
    if (view.IsAttachedToWindow && localDisposable is not null)
    {
        action();
        localDisposable.Dispose();
    }
    // ⚠️ Missing: else { localDisposable?.Dispose(); } 
});

Recommendation: Dispose the local disposable in all code paths inside the Post callback:

var localDisposable = disposable;
disposable = null;
view.Post(() =>
{
    if (view.IsAttachedToWindow && localDisposable is not null)
    {
        action();
    }
    localDisposable?.Dispose();
});

Severity: Minor — the handler itself is lightweight and the scenario (view detaching between attach event and next looper iteration) is rare. Not a blocker.


2. Missing newline at end of test file

File: src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue14364.cs

The diff shows \ No newline at end of file at the end of this file. Most editors and git tooling prefer a trailing newline.

Recommendation: Add a newline character at the end of the file.

Severity: Minor / style.


3. Test validates Label but issue #14364 reports CollectionView

File: src/Controls/tests/TestCases.HostApp/Issues/Issue14364.cs

Problem: Issue #14364 specifically reports that CollectionView height, width, and LogicalChildren are not available during Loaded. The test uses a Label inside a Grid with fixed HeightRequest/WidthRequest. While a Label is a simpler repro and exercises the same OnLoaded code path, it doesn't fully validate the CollectionView scenario. In particular, LogicalChildren.Count — which was explicitly listed as broken in the issue — is not tested.

Assessment: The core fix is in OnLoaded in ViewExtensions.cs, which is shared by all views including CollectionView. Testing with a Label does exercise the fix. This is a pragmatic tradeoff (simpler HostApp test, easier to make reliable). Not a blocker.

Recommendation (optional): Consider adding a comment in the test explaining why Label is used instead of CollectionView.

Severity: Minor / informational.


✅ Looks Good

  • Core fix is sound: view.Post() is the correct Android idiom for deferring work to after the layout pass. This is well-established practice.
  • IsAttachedToWindow guard: Adding view.IsAttachedToWindow check inside the Post callback correctly handles the race where a view is detached before the callback runs. This was recommended by reviewer jsuarezruiz and was incorporated.
  • localDisposable pattern: Capturing disposable into a local before setting it to null is the right approach for allowing cancellation detection in async callbacks.
  • Both issues addressed: The fix correctly addresses both CollectionView on Android does not provide height, width, logical children once loaded, works fine on Windows #14364 (control sizes not available in Loaded) and Control's Loaded event invokes before calling its measure override method. #14160 (Loaded fires before MeasureOverride).
  • Cross-platform safety: The change is scoped to the Android platform file (Platform/Android/ViewExtensions.cs) and does not affect iOS/Windows/Mac paths.
  • Tests added: Both a HostApp page and a SharedTests NUnit test were added, following the correct two-project pattern.
  • No breaking changes: The behavioral change (slight delay in Loaded event firing) is the intended fix and aligns with user expectations.

@rmarinho rmarinho added s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 18, 2026
@kubaflo kubaflo added s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-win AI found a better alternative fix than the PR s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad labels Feb 20, 2026
@Vignesh-SF3580
Copy link
Copy Markdown
Contributor Author

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionUpdate ViewExtensions.cs · bddc900
Issue: #14364 - CollectionView/Controls on Android do not provide valid height/width/size during Loaded event PR: #31590 - [Android] Fix control size properties not available during Loaded event Platforms Affected: Android only (platform/android label) Files Changed: 1 implementation file, 2 test files Author: Vignesh-SF3580 (Syncfusion partner)

Issue Summary

On Android, the Loaded event fires before the layout pass completes, causing controls to report incorrect dimensions (Height: -1, Width: -1). This works correctly on Windows/iOS where the layout pass completes before Loaded fires.

Fix Approach

In src/Core/src/Platform/Android/ViewExtensions.cs, inside the OnLoaded method's ViewAttachedToWindow event handler, the fix wraps the action() call with view.Post() to defer execution to after the current layout pass, plus an IsAttachedToWindow guard to handle cases where the view may be detached between the event and the post execution.

Before:

disposable?.Dispose();
disposable = null;
action();

After:

disposable?.Dispose();
disposable = null;
view.Post(() =>
{
    if (view.IsAttachedToWindow)
    {
        action();
    }
});

PR Discussion Summary

  • jsuarezruiz (reviewer) suggested adding IsAttachedToWindow guard since the action runs the view may be detached before executionasynchronously
  • Author updated code to incorporate the suggestion

Key Reviewer Feedback

Reviewer Comment Status
jsuarezruiz Add guard inside Post callback Implemented

Edge Cases to Consider

  • If view is detached between ViewAttachedToWindow firing and Post() handled by IsAttachedToWindow checkexecuting
  • Memory leak if action captures large objects and view is mitigated by guarddetached
  • Timing: disposable is disposed before Post(), but the lambda still captures view and action

Fix Candidates

Source Approach Test Result Files Changed Notes

PR PR #31590 Wrap action() in view.Post() with IsAttachedToWindow PENDING (Gate) ViewExtensions.cs (+7/-1) Original PR guard
🚦 Gate — Test Verification
📝 Review SessionUpdate ViewExtensions.cs · bddc900
Result PASSED: Platform: android Mode: Full Verification

  • Tests FAIL without fix
  • Tests PASS with fix

Check Expected Actual Result
Tests WITHOUT fix FAIL FAIL
Tests WITH fix PASS PASS
Conclusion: The tests properly validate the fix and catch the bug when it's present.

🔧 Fix — Analysis & Comparison
📝 Review SessionUpdate ViewExtensions.cs · bddc900

🔧 Fix Phase

Fix Candidates

Source Approach Test Result Files Changed Notes

PR PR #31590 view.Post(() => { if (view.IsAttachedToWindow) action(); }) ✅ PASS (Gate) 1 file Simple, idiomatic Android pattern
1 try-fix ViewTreeObserver.AddOnGlobalLayoutListener (global layout listener) ✅ PASS 1 file Works but more verbose; fires after any view layout
2 try-fix Width>0|Height>0 check + view.Post() fallback ✅ PASS 1 file Works but almost always takes Post() branch — effectively same as PR
3 try-fix view.IsLaidOut + AddOnLayoutChangeListener (per-view listener) ✅ PASS 1 file More targeted than global VTO but adds listener lifecycle complexity

Cross-Pollination Summary

Round Model Response
1 claude-opus-4.6 NO NEW IDEAS
1 gpt-5.2 NEW IDEA → IsLaidOut + AddOnLayoutChangeListener (used for attempt 3)
1 gpt-5.2-codex NEW IDEA → OnPreDrawListener (variant of ViewTreeObserver, skipped - covered by attempt 1)
1 gemini-3-pro-preview NO NEW IDEAS
1 claude-sonnet-4.5 NEW IDEA → Choreographer.PostFrameCallback (more complex view.Post variant, skipped)
2 gpt-5.2 NEW IDEA → MessageQueue.AddIdleHandler (over-engineered, less precise)
2 gpt-5.2-codex NO NEW IDEAS
2 claude-sonnet-4.5 NEW IDEA → AddOnAttachStateChangeListener (conceptually wrong — this IS the broken old approach)
Exhausted: Yes (Round 2 ideas are not better — more complex or conceptually flawed)

Selected Fix: PR's fix — simplest, most idiomatic Android pattern. All 3 alternatives also pass but are more verbose with no practical benefit.

📋 Report — Final Recommendation
📝 Review SessionUpdate ViewExtensions.cs · bddc900

📋 Report Phase

Recommendation: ✅ APPROVE

PR Finalize Analysis

✅ Title: Good — No Change Needed

Current: [Android] Fix control size properties not available during Loaded event

The title accurately reflects the platform ([Android]), the component (control size properties), and the behavior being fixed. It's descriptive and searchable.

✅ Description: Good — Minor Enhancement Suggested

Quality assessment:

  • Structure: ✅ Clear sections with headers
  • Technical depth: ✅ Includes root cause section
  • Accuracy: ✅ Matches actual implementation
  • Completeness: ✅ NOTE block present, issues fixed listed, platforms tested, screenshots
  • Agent context: ⚠️ Missing IsAttachedToWindow rationale and "What NOT to Do" notes

The existing description is good overall. Only minor additions are suggested:

Suggested Addition to Description

After "Description of Change" section, add:

**Key detail:** `view.Post()` queues execution for the next Looper cycle (after the layout pass), ensuring `Width` and `Height` are valid. The `IsAttachedToWindow` guard prevents the action from firing if the view was detached between the `ViewAttachedToWindow` event and post execution.

### What NOT to Do (for future agents)

- ❌ **Don't use ViewTreeObserver.AddOnGlobalLayoutListener** — Works but fires after ANY view layout in the window, making it overly broad and harder to maintain
- ❌ **Don't check Width/Height > 0 before calling action()** — At `ViewAttachedToWindow` time, dimensions are always -1, so the check always falls through to `Post()` anyway (identical behavior, more code)
- ❌ **Don't use `AddOnLayoutChangeListener` with `IsLaidOut`** — More targeted than global VTO, but adds unnecessary listener lifecycle complexity for the same result

Code Review Findings

✅ Looks Good

  • Minimal change: Only 7 lines changed in the fix file. The smallest possible change that fixes the root cause
  • Idiomatic Android pattern: view.Post() is the standard Android idiom for deferring work to after layout
  • Guard clause: IsAttachedToWindow check correctly prevents action firing if view is detached between event and execution
  • Test quality: Tests properly assert that dimensions are NOT -1 (the broken state), rather than asserting a specific size (which would be fragile)
  • Test class inheritance: Uses TestShell indirectly via Shell base — appropriate for this Shell-based navigation scenario

🟡 Minor Observations

  1. Test asserts Not.EqualTo("Height: -1, Width: -1") — This test is correctly checking for the broken state. However, it doesn't validate actual positive dimensions. This is acceptable for a regression test (proving it's not broken).
  2. Issue14364 uses TestShell-equivalent pattern but extends Shell directly instead of TestShell. This is fine — the issue is Shell-navigation specific and the author chose a clean custom implementation.
  3. disposable is disposed before Post() — The action lambda still captures view and action. This is intentional and correct: the disposable manages the event subscription, not the deferred work.

🔴 No Critical Issues Found

Summary of Findings

Phase Completion Status

Phase Status Notes
✅ Pre-Flight Complete PR context gathered, fix understood
✅ Gate PASSED Tests FAIL without fix, PASS with fix (Android)
✅ Fix Complete 3 alternatives explored, all pass, PR's fix is simplest
✅ Report Complete This document

Fix Validation Summary

Source Approach Test Result

PR PR #31590 view.Post() + IsAttachedToWindow guard ✅ PASS (Gate verified)
1 try-fix ViewTreeObserver.AddOnGlobalLayoutListener ✅ PASS
2 try-fix Width>0/Height>0 check + Post fallback ✅ PASS
3 try-fix view.IsLaidOut + AddOnLayoutChangeListener ✅ PASS
Cross-pollination: 2 rounds with 5 models. Round 2 yielded no new viable alternatives.

Selected Fix: PR's fix — All 4 approaches pass the test. The PR's approach is the simplest, most idiomatic, and uses the least code.

Final Recommendation

✅ APPROVE — The PR correctly fixes a real Android-specific timing bug:

  • Root cause is confirmed: ViewAttachedToWindow fires before layout completes on Android
  • Fix is correct: view.Post() defers execution to after the current layout pass
  • Guard is appropriate: IsAttachedToWindow prevents leaking action execution after detach
  • Test validates the fix properly
  • Three independently-generated alternative fixes all confirm the approach space is well-covered
  • The PR's implementation is the simplest of all valid alternatives

📋 Expand PR Finalization Review

I’ve updated the code to match the !view.IsLoaded() cancellation pattern by deferring disposal into the Post callback. Issues 14364 and 14160 cover the same scenario, so no separate test is needed for 14160. There are no major concerns with the remaining comments.

@sheiksyedm sheiksyedm added this to the .NET 10 SR6 milestone Mar 2, 2026
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@PureWeen PureWeen modified the milestones: .NET 10 SR6, .NET 10 SR7 Mar 3, 2026
@kubaflo kubaflo added s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) and removed s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) labels Mar 7, 2026
Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

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

Looks like tests are failing. Could you verify if the failures are related to the changes?

@Vignesh-SF3580
Copy link
Copy Markdown
Contributor Author

Vignesh-SF3580 commented Mar 10, 2026

Looks like tests are failing. Could you verify if the failures are related to the changes?

@kubaflo The fix is Android-specific. I verified the failing Android UI test "LayoutShouldBeCorrectOnFirstNavigation", and it passed locally. The test failures are not related to this fix.
image

@kubaflo kubaflo changed the base branch from main to inflight/current March 10, 2026 12:26
@kubaflo kubaflo merged commit e91dc95 into dotnet:inflight/current Mar 10, 2026
144 of 159 checks passed
PureWeen pushed a commit that referenced this pull request Mar 11, 2026
…nt (#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes #14364
Fixes #14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
github-actions bot pushed a commit that referenced this pull request Mar 11, 2026
…nt (#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes #14364
Fixes #14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
@PureWeen PureWeen mentioned this pull request Mar 17, 2026
PureWeen pushed a commit that referenced this pull request Mar 19, 2026
…nt (#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes #14364
Fixes #14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
github-actions bot pushed a commit that referenced this pull request Mar 20, 2026
…nt (#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes #14364
Fixes #14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
github-actions bot pushed a commit that referenced this pull request Mar 22, 2026
…nt (#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes #14364
Fixes #14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
PureWeen added a commit that referenced this pull request Mar 24, 2026
## What's Coming

.NET MAUI inflight/candidate introduces significant improvements across
all platforms with focus on quality, performance, and developer
experience. This release includes 66 commits with various improvements,
bug fixes, and enhancements.


## Activityindicator
- [Android] Implemented material3 support for ActivityIndicator by
@Dhivya-SF4094 in #33481
  <details>
  <summary>🔧 Fixes</summary>

- [Implement material3 support for
ActivityIndicator](#33479)
  </details>

- [iOS] Fix: ActivityIndicator IsRunning ignores IsVisible when set to
true by @bhavanesh2001 in #28983
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [ActivityIndicator] `IsRunning` ignores `IsVisible` when set to
`true`](#28968)
  </details>

## Button
- [iOS] Button RTL text and image overlap - fix by @kubaflo in
#29041

## Checkbox
- [iOS/MacCatalyst] Fix CheckBox foreground color not resetting when set
to null by @Ahamed-Ali in #34284
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color of the checkBox control is not properly worked on dynamic
scenarios](#34278)
  </details>

## CollectionView
- [iOS] Fix: CollectionView does not clear selection when SelectedItem
is set to null by @Tamilarasan-Paranthaman in
#30420
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView not being able to remove selected item highlight on
iOS](#30363)
- [[MAUI] Select items traces are
preserved](#26187)
  </details>

- [iOS] CV2 ItemsLayout update by @kubaflo in
#28675
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView CollectionViewHandler2 doesnt change ItemsLayout on
DataTrigger](#28656)
- [iOS CollectionView doesn't respect a change to ItemsLayout when using
Items2.CollectionViewHandler2](#31259)
  </details>

- [iOS][CV2] Fix CollectionView renders large empty space at bottom of
view by @devanathan-vaithiyanathan in
#31215
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [MacCatalyst] CollectionView renders large empty space at
bottom of view](#17799)
- [[iOS/Mac] CollectionView2 EmptyView takes up large horizontal space
even when the content is
small](#33201)
  </details>

- [iOS] Fixed issue where group Header/Footer template was set to all
items when IsGrouped was true for an ObservableCollection by
@Tamilarasan-Paranthaman in #29144
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Group Header/Footer Repeated for All Items When IsGrouped is
True for ObservableCollection in
CollectionView](#29141)
  </details>

- [Android] Fix CollectionView selection crash with HeaderTemplate by
@NirmalKumarYuvaraj in #34275
  <details>
  <summary>🔧 Fixes</summary>

- [[Bug] [Android] System.ArgumentOutOfRangeException: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index](#34247)
  </details>

## DateTimePicker
- [iOS] Fix TimePicker AM/PM frequently changes when the app is closed
and reopened by @devanathan-vaithiyanathan in
#31066
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] TimePicker AM/PM frequently changes when the app is closed and
reopened](#30837)
- [Maui 10 iOS TimePicker Strange Characters in place of
AM/PM](#33722)
  </details>

- Android TimePicker ignores 24 hour system setting when using Format
Property - fix by @kubaflo in #28797
  <details>
  <summary>🔧 Fixes</summary>

- [Android TimePicker ignores 24 hour system setting when using Format
Property](#28784)
  </details>

## Drawing
- [iOS, Mac, Windows] GraphicsView: Fix Background/BackgroundColor not
updating by @NirmalKumarYuvaraj in
#31254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Mac, Windows] GraphicsView does not change the
Background/BackgroundColor](#31239)
  </details>

- [iOS] GraphicsView DrawString - fix by @kubaflo in
#26304
  <details>
  <summary>🔧 Fixes</summary>

- [DrawString not rendering in
iOS.](#24450)
- [GraphicsView DrawString not rendering in
iOS](#8486)
- [DrawString doesn't work on
maccatalyst](#4993)
  </details>

- [Android] - Fix Shadow Rendering For Transparent Fill, Stroke (Lines),
and Text on Shapes by @prakashKannanSf3972 in
#29528
  <details>
  <summary>🔧 Fixes</summary>

- [Ellipse Transparency Not Rendered When Drawing Arc Inside the Ellipse
Using GraphicsView on
Android](#29394)
  </details>

- Revert "[iOS, Mac, Windows] GraphicsView: Fix
Background/BackgroundColor not updating (#31254)" by @Ahamed-Ali via
@Copilot in #34508

## Entry
- [iOS 26] Fix Entry MaxLength not enforced due to new multi-range
delegate by @kubaflo in #32045
  <details>
  <summary>🔧 Fixes</summary>

- [iOS 26 - The MaxLength property value is not respected on an Entry
control.](#32016)
- [.NET MAUI Entry Maximum Length not working on iOS and
macOS](#33316)
  </details>

- [iOS] Fixed Entry with IsPassword toggling loses previously entered
text by @SubhikshaSf4851 in #30572
  <details>
  <summary>🔧 Fixes</summary>

- [Entry with IsPassword toggling loses previously entered text on iOS
when IsPassword is
re-enabled](#30085)
  </details>

## Essentials
- Fix for FilePicker PickMultipleAsync nullable reference type by
@SuthiYuvaraj in #33163
  <details>
  <summary>🔧 Fixes</summary>

- [FilePicker PickMultipleAsync nullable reference
type](#33114)
  </details>

- Replace deprecated NetworkReachability with NWPathMonitor on iOS/macOS
by @jfversluis via @Copilot in #32354
  <details>
  <summary>🔧 Fixes</summary>

- [NetworkReachability is obsolete on iOS/maccatalyst
17.4+](#32312)
- [Use NWPathMonitor on iOS for Essentials
Connectivity](#2574)
  </details>

## Essentials Connectivity
- Update Android Connectivity implementation to use modern APIs by
@jfversluis via @Copilot in #30348
  <details>
  <summary>🔧 Fixes</summary>

- [Update the Android Connectivity implementation to user modern
APIs](#30347)
  </details>

## Flyout
- [iOS] Fixed Flyout icon not updating when root page changes using
InsertPageBefore by @Vignesh-SF3580 in
#29924
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Flyout icon not replaced by back button when root page is
changed using
InsertPageBefore](#29921)
  </details>

## Flyoutpage
- [iOS] Flyout Items Not Displayed in RightToLeft FlowDirection in
Landscape - fix by @kubaflo in #26762
  <details>
  <summary>🔧 Fixes</summary>

- [Flyout Items Not Displayed in RightToLeft FlowDirection on iOS in
Landscape Orientation and Hamburger Icon Positioned
Incorrectly](#26726)
  </details>

## Image
- [Android] Implemented Material3 support for Image by @Dhivya-SF4094 in
#33661
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Image](#33660)
  </details>

## Keyboard
- [iOS] Fix gap at top of view after rotating device while Entry
keyboard is visible by @praveenkumarkarunanithi in
#34328
  <details>
  <summary>🔧 Fixes</summary>

- [Focusing and entering texts on entry control causes a gap at the top
after rotating simulator.](#33407)
  </details>

## Label
- [Android] Support for images inside HTML label by @kubaflo in
#21679
  <details>
  <summary>🔧 Fixes</summary>

- [Label with HTML TextType does not display images on
Android](#21044)
  </details>

- [fix] ContentLabel Moved to a nested class to prevent CS0122 in
external source generators by @SubhikshaSf4851 in
#34514
  <details>
  <summary>🔧 Fixes</summary>

- [[MAUI] Building Maui App with sample content results CS0122
errors.](#34512)
  </details>

## Layout
- Optimize ordering of children in Flex layout by @symbiogenesis in
#21961

- [Android] Fix control size properties not available during Loaded
event by @Vignesh-SF3580 in #31590
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView on Android does not provide height, width, logical
children once loaded, works fine on
Windows](#14364)
- [Control's Loaded event invokes before calling its measure override
method.](#14160)
  </details>

## Mediapicker
- [iOS/Android] MediaPicker: Fix image orientation when RotateImage=true
by @michalpobuta in #33892
  <details>
  <summary>🔧 Fixes</summary>

- [MediaPicker.PickPhotosAsync does not preserve image
orientation](#32650)
  </details>

## Modal
- [Windows] Fix modal page keyboard focus not shifting to newly opened
modal by @jfversluis in #34212
  <details>
  <summary>🔧 Fixes</summary>

- [Keyboard focus does not shift to a newly opened modal page: Pressing
enter clicks the button on the page beneath the modal
page](#22938)
  </details>

## Navigation
- [iOS26] Apply view margins in title view by @kubaflo in
#32205
  <details>
  <summary>🔧 Fixes</summary>

- [NavigationPage TitleView iOS
26](#32200)
  </details>

- [iOS] System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle() by @kubaflo in
#29564
  <details>
  <summary>🔧 Fixes</summary>

- [System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle()](#29535)
  </details>

- [iOS 26] Fix back button color not applied for NavigationPage by
@Shalini-Ashokan in #34326
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color not applied to the Back button text or image on iOS
26](#33966)
  </details>

## Picker
- Fix Picker layout on Mac Catalyst 26+ by @kubaflo in
#33146
  <details>
  <summary>🔧 Fixes</summary>

- [[MacOS 26] Text on picker options are not centered on macOS
26.1](#33229)
  </details>

## Progressbar
- [Android] Implemented Material3 support for ProgressBar by
@SyedAbdulAzeemSF4852 in #33926
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Progressbar](#33925)
  </details>

## RadioButton
- [iOS, Mac] Fix for RadioButton TextColor for plain Content not working
by @HarishwaranVijayakumar in #31940
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton: TextColor for plain Content not working on
iOS](#18011)
  </details>

- [All Platforms] Fix RadioButton warning when ControlTemplate is set
with View content by @kubaflo in
#33839
  <details>
  <summary>🔧 Fixes</summary>

- [Seeking clarification on RadioButton + ControlTemplate + Content
documentation](#33829)
  </details>

- Visual state change for disabled RadioButton by @kubaflo in
#23471
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton disabled UI issue -
iOS](#18668)
  </details>

## SafeArea
- [Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not
extending to system navigation bar by @praveenkumarkarunanithi in
#33428
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] TabbedPage BottomNavigation BarBackgroundColor does not
extend to system navigation bar area in Edge-to-Edge
mode](#33344)
  </details>

## ScrollView
- [Android] ScrollView: Fix HorizontalScrollBarVisibility not updating
immediately at runtime by @SubhikshaSf4851 in
#33528
  <details>
  <summary>🔧 Fixes</summary>

- [Runtime Scrollbar visibility not updating correctly on Android and
macOS platforms.](#33400)
  </details>

- Fixed crash when calling ItemsView.ScrollTo on unloaded CollectionView
by @kubaflo in #25444
  <details>
  <summary>🔧 Fixes</summary>

- [App crashes when calling ItemsView.ScrollTo on unloaded
CollectionView](#23014)
  </details>

## Shell
- [Shell] Update logic for iOS large title display in ShellItemRenderer
by @kubaflo in #33246

- [iOS][Shell] Fix navigation lifecycle and back button for More tab (>5
tabs) by @kubaflo in #27932
  <details>
  <summary>🔧 Fixes</summary>

- [OnAppearing and OnNavigatedTo does not work when using extended
Tabbar (tabbar with more than 5 tabs) on
IOS.](#27799)
- [Shell.BackButtonBehavior does not work when using extended Tabbar
(tabbar with more than 5 tabs)on
IOS.](#27800)
- [Shell TabBar More button causes ViewModel command binding
disconnection on back
navigation](#30862)
- [Content page onappearing not firing if tabs are on the more tab on
IOS](#31166)
  </details>

- [iOS 26] Fix tab bar ghosting when navigating from modal to tabbed
Shell content by @SubhikshaSf4851 in
#34254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Tab bar ghosting issue on iOS 26 (liquid
glass)](#34143)
  </details>

- Fix for Shell tab visibility not updating when navigating back
multiple pages by @BagavathiPerumal in
#34403
  <details>
  <summary>🔧 Fixes</summary>

- [Changing Shell Tab Visibility when navigating back multiple pages
ignores Shell Tab
Visibility](#33351)
  </details>

- [iOS/Mac] Fixed OnBackButtonPressed not firing for Shell Navigation
Bar Button by @Dhivya-SF4094 in
#34401
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] OnBackButtonPressed not firing for Shell Navigation Bar
button](#34190)
  </details>

## Slider
- [iOS] Fix for Slider ThumbImageSource is not centered properly on iOS
26 by @HarishwaranVijayakumar in
#34019
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS 26] Slider ThumbImageSource is not centered
properly](#33967)
  </details>

- [Android] Fix improper rendering of ThumbimageSource in Slider by
@NirmalKumarYuvaraj in #34064
  <details>
  <summary>🔧 Fixes</summary>

- [[Slider] MAUI Slider thumb image is big on
android](#13258)
  </details>

## Stepper
- [iOS] Fix Stepper layout overlap in landscape on iOS 26 by
@Vignesh-SF3580 in #34325
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] D10 - Customize cursor position - Rotating simulator makes
the button and label
overlap](#34273)
  </details>

## SwipeView
- [iOS] SwipeView: Honor FontImageSource.Color in SwipeItem icon by
@kubaflo in #27389
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] SwipeView: SwipeItem.IconImageSource.FontImageSource color
value not honored](#27377)
  </details>

## Switch
- [Android] Fix Switch thumb shadow missing when ThumbColor is set by
@Shalini-Ashokan in #33960
  <details>
  <summary>🔧 Fixes</summary>

- [Android Switch Control Thumb
Shadow](#19676)
  </details>

## Toolbar
- [iOS/Mac Catalyst 26] Fix Shell.ForegroundColor not applied to
ToolbarItems by @SyedAbdulAzeemSF4852 in
#34085
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS26] Shell.ForegroundColor is not applied to
ToolbarItems](#34083)
  </details>

- [Android] VoiceOver on Toolbar Item by @kubaflo in
#29596
  <details>
  <summary>🔧 Fixes</summary>

- [VoiceOver on Toolbar
Item](#29573)
- [SemanticProperties do not work on
ToolbarItems](#23623)
  </details>


<details>
<summary>🧪 Testing (11)</summary>

- [Testing] Additional Feature Matrix Test Cases for CollectionView by
@TamilarasanSF4853 in #32432
- [Testing] Feature Matrix UITest Cases for VisualStateManager by
@LogishaSelvarajSF4525 in #34146
- [Testing] Feature Matrix UITest Cases for Clip by @TamilarasanSF4853
in #34121
- [Testing] Feature matrix UITest Cases for Map Control by
@HarishKumarSF4517 in #31656
- [Testing] Feature matrix UITest Cases for Visual Transform Control by
@HarishKumarSF4517 in #32799
- [Testing] Feature Matrix UITest Cases for Shell Pages by
@NafeelaNazhir in #33945
- [Testing] Feature Matrix UITest Cases for Triggers by
@HarishKumarSF4517 in #34152
- [Testing] Refactoring Feature Matrix UITest Cases for CheckBox Control
by @LogishaSelvarajSF4525 in #34283
- Resolve UI test Build Sample failures - Candidate March 16 by
@Ahamed-Ali in #34442
- Fix the failures in the Candidate branch- March 16 by @Ahamed-Ali in
#34453
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>
- Fixed the iOS 18.5 Candidate failures (March 16,2026) by @Ahamed-Ali
in #34593
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>

</details>

<details>
<summary>📦 Other (2)</summary>

- Fixed candidate test failures caused by PR #33428. by @Ahamed-Ali in
#34515
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] On Android, there's a big space at the top for I, M and N2 &
N3](#34509)
  </details>
- Revert "[iOS] Button RTL text and image overlap - fix (#29041)" in
b0497af

</details>

<details>
<summary>📝 Issue References</summary>

Fixes #2574, Fixes #4993, Fixes #8486, Fixes #13258, Fixes #14160, Fixes
#14364, Fixes #17799, Fixes #18011, Fixes #18668, Fixes #19676, Fixes
#21044, Fixes #22938, Fixes #23014, Fixes #23623, Fixes #24450, Fixes
#26187, Fixes #26726, Fixes #27377, Fixes #27799, Fixes #27800, Fixes
#28656, Fixes #28784, Fixes #28968, Fixes #29141, Fixes #29394, Fixes
#29535, Fixes #29573, Fixes #29921, Fixes #30085, Fixes #30347, Fixes
#30363, Fixes #30837, Fixes #30862, Fixes #31166, Fixes #31239, Fixes
#31259, Fixes #32016, Fixes #32200, Fixes #32312, Fixes #32650, Fixes
#33114, Fixes #33201, Fixes #33229, Fixes #33316, Fixes #33344, Fixes
#33351, Fixes #33400, Fixes #33407, Fixes #33479, Fixes #33660, Fixes
#33722, Fixes #33829, Fixes #33925, Fixes #33966, Fixes #33967, Fixes
#34083, Fixes #34143, Fixes #34190, Fixes #34247, Fixes #34273, Fixes
#34278, Fixes #34437, Fixes #34509, Fixes #34512

</details>

**Full Changelog**:
main...inflight/candidate
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 30, 2026
…nt (dotnet#31590)

<!-- 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!

### Issue Details
On Android, controls do not provide valid size when the Loaded event
fires.



### Root Cause
On Android, the Loaded event fires before the layout pass completes,
causing views to report incorrect dimensions.

### Description of Change
Modified OnLoaded method to use view.Post() instead of immediate action
execution, ensuring the Loaded event fires after the layout pass
completes.

### Tested the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed

Fixes dotnet#14364
Fixes dotnet#14160

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/703766e7-c3e8-4b9d-bdc0-5a2b943cd060">
| <img width="500" height="300" alt="image"
src="https://github.com/user-attachments/assets/3fa34f58-c3f1-49ca-b638-29028930d4fd">
|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-approved AI agent recommends approval - PR fix is correct and optimal s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

8 participants