Skip to content

[Android] Fix excessive memory usage for stream and resource-based image loading#33590

Merged
PureWeen merged 4 commits intodotnet:inflight/currentfrom
Shalini-Ashokan:fix-33239
Feb 23, 2026
Merged

[Android] Fix excessive memory usage for stream and resource-based image loading#33590
PureWeen merged 4 commits intodotnet:inflight/currentfrom
Shalini-Ashokan:fix-33239

Conversation

@Shalini-Ashokan
Copy link
Copy Markdown
Contributor

@Shalini-Ashokan Shalini-Ashokan commented Jan 19, 2026

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

Stream-based and resource-based image loading consumed excessive memory on Android versus XAML image loading. Images were loaded at display dimensions instead of original dimensions, affecting all apps using embedded resources or streams.

Root Cause

Glide upscaled stream-based images to display dimensions without size constraints. XAML had proper size handling, but stream loading lacked overrides, causing memory to scale with screen size not image size.

Description of Change

Added size override in PlatformInterop.java to preserve original image dimensions. This prevents upscaling to display dimensions, making all loading methods produce consistent memory usage.

Validated the behavior in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Issues Fixed

Fixes #33239

Output ScreenShot

Before After
33239-BeforeFix 33239-AfterFix

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

Hey there @@Shalini-Ashokan! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@sheiksyedm sheiksyedm marked this pull request as ready for review January 22, 2026 15:10
Copilot AI review requested due to automatic review settings January 22, 2026 15:10
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 excessive memory usage when loading images from streams or resources on Android by preventing Glide from upscaling images to display dimensions. The fix adds override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to stream-based image loading paths in PlatformInterop.java, ensuring images maintain their original dimensions rather than being scaled to match the display size.

Changes:

  • Added size override to loadImageFromStream methods to prevent Glide upscaling
  • Created UI test to verify image byte count remains reasonable for stream-based loading
  • Created test page demonstrating the issue with embedded resource image loading

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java Added .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream methods to prevent image upscaling
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33239.cs Added Android-specific UI test verifying image byte count after loading from resource
src/Controls/tests/TestCases.HostApp/Issues/Issue33239.cs Added test page with embedded resource image and button to measure bitmap memory usage

App.WaitForElement("MeasureButton");
App.Tap("MeasureButton");
var resultText = App.FindElement("ResultLabel").GetText();
Assert.That(resultText, Is.EqualTo("Image ByteCount: 786432"));
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The hard-coded byte count value (786432) in this assertion is brittle and may cause test failures across different devices or Android versions. The actual byte count can vary based on bitmap configuration, pixel density, or image decoding behavior. Consider using a range check or verifying that the byte count is within a reasonable threshold of the expected original image dimensions instead of an exact match.

Suggested change
Assert.That(resultText, Is.EqualTo("Image ByteCount: 786432"));
var prefix = "Image ByteCount: ";
Assert.That(resultText, Does.StartWith(prefix), "Result text did not start with the expected prefix.");
var byteCountText = resultText.Substring(prefix.Length).Trim();
if (!int.TryParse(byteCountText, out var byteCount))
{
Assert.Fail($"Unable to parse byte count from result text: '{resultText}'");
}
const int expectedByteCount = 786432;
var tolerance = (int)(expectedByteCount * 0.2); // allow 20% variance
Assert.That(
byteCount,
Is.InRange(expectedByteCount - tolerance, expectedByteCount + tolerance),
$"Expected image byte count to be within ±{tolerance} of {expectedByteCount}, but was {byteCount}.");

Copilot uses AI. Check for mistakes.
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 18, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionModified the test cases · eb7bec7

Issue: #33239 - [Android] Unexpected high Bitmap.ByteCount when loading image via ImageSource.FromResource() or ImageSource.FromStream() in .NET MAUI
PR: #33590 - [Android] Fix excessive memory usage for stream and resource-based image loading
Author: Shalini-Ashokan (community contributor, partner/syncfusion)
Platforms Affected: Android only
Files Changed: 1 fix file, 2 test files, 1 snapshot file

Issue Summary

On Android, loading images via ImageSource.FromResource() or ImageSource.FromStream() caused ~25MB Bitmap.ByteCount vs ~1MB for XAML-referenced images. Root cause: Glide (Android image loading library) upscaled stream-based images to display dimensions without size constraints, while XAML image loading had proper size handling.

Fix Approach

Added .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream methods in PlatformInterop.java. This prevents Glide from upscaling images to display size, keeping them at their original dimensions.

Files Changed

Fix files:

  • src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java (+4/-2) — Two loadImageFromStream methods updated

Test files:

  • src/Controls/tests/TestCases.HostApp/Issues/Issue33239.cs (+106) — New HostApp page with embedded resource image and byte count measurement
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33239.cs (+25) — Android UI test asserting resource ByteCount equals file ByteCount
  • src/Controls/tests/TestCases.Android.Tests/snapshots/android/DownSizeImageAppearProperly.png — Modified snapshot

Prior Review Note

A prior agent review (at commit 4a23114) requested changes due to a hardcoded byte count value (786432) in the test assertion. The author has since updated the test to compare resource image ByteCount vs file image ByteCount directly (Assert.That(resource, Is.EqualTo(file))), which is device-independent and more robust.

Reviewer Feedback

  • copilot-pull-request-reviewer previously flagged hardcoded byte count — RESOLVED by author's test update
  • Test change in current commit: now compares ResourceImageLabel vs FileImageLabel text, not hardcoded value

Disagreements / Open Questions

None — prior issues resolved.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33590 Add .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream methods in PlatformInterop.java ⏳ PENDING (Gate) PlatformInterop.java (+4/-2) Original PR

🚦 Gate — Test Verification
📝 Review SessionModified the test cases · eb7bec7

Result: ✅ PASSED
Platform: android
Mode: Full Verification (RequireFullVerification)
TestFilter: Issue33239

  • Tests FAIL without fix ✅ (bug detected correctly)
  • Tests PASS with fix ✅ (fix works correctly)

Fix Files Detected:

  • src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java

🔧 Fix — Analysis & Comparison
📝 Review SessionModified the test cases · eb7bec7

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-sonnet-4.5) .centerInside() transformation on both loadImageFromStream methods ✅ PASS PlatformInterop.java (+2/-2) Prevents upscaling via transformation layer
2 try-fix (claude-opus-4.6) .downsample(DownsampleStrategy.NONE) on both loadImageFromStream methods ✅ PASS PlatformInterop.java (+3/-2) Disables decode-level upsampling entirely
3 try-fix (gpt-5.2) .downsample(DownsampleStrategy.AT_MOST) on both loadImageFromStream methods ✅ PASS PlatformInterop.java (+3/-2) Prevents upscaling; allows downscaling
4 try-fix (gpt-5.2-codex) Read stream to byte[], decode bounds, override with explicit width/height ✅ PASS PlatformInterop.java (~60 lines) Bypasses view size measurement; very invasive
5 try-fix (gemini-3-pro-preview) .downsample(DownsampleStrategy.CENTER_INSIDE) on both loadImageFromStream methods ✅ PASS PlatformInterop.java (+3/-2) Prevents upscaling; allows downscaling; semantically clear
6 try-fix (gpt-5.2) Downsampler.FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS=false ❌ FAIL PlatformInterop.java (+4/-2) Deep Glide internal; doesn't affect this decode path
PR PR #33590 .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) on both loadImageFromStream methods ✅ PASS (Gate) PlatformInterop.java (+4/-2) Original PR fix; consistent with loadImageFromFont pattern in same file

Cross-Pollination Summary (Round 2)

Model Response
claude-sonnet-4.5 Suggested thumbnail/format/cache ideas but concluded NO NEW IDEAS worth pursuing
claude-opus-4.6 NO NEW IDEAS — confirmed the Glide API surface is exhausted
gpt-5.2 NEW IDEA: DISABLE_BITMAP_POOL — tangential (controls memory reuse, not decode size)
gpt-5.2-codex NEW IDEA: .disallowHardwareConfig() — unrelated to decode-phase upscaling
gemini-3-pro-preview NO NEW IDEAS

Exhausted: Yes — remaining suggestions are tangential to decode-phase upscaling and won't yield better results.

Selected Fix: PR's fix — .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)

Reason: The PR's fix uses the same pattern as loadImageFromFont already uses in PlatformInterop.java, maintaining internal consistency. It is semantically explicit ("load at original dimensions") and directly addresses the root cause. While DownsampleStrategy.CENTER_INSIDE or AT_MOST (Attempts 3 and 5) could be argued as more memory-efficient for large images (they allow beneficial downscaling), the PR's approach is the correct semantic for a stream/resource load where the developer controls display size via the Image control's Aspect/HeightRequest/WidthRequest properties. The agent could NOT beat the PR's fix.


📋 Report — Final Recommendation
📝 Review SessionModified the test cases · eb7bec7

✅ Final Recommendation: APPROVE

Summary

PR #33590 fixes a genuine Android memory bug where ImageSource.FromResource() and ImageSource.FromStream() caused ~25MB Bitmap.ByteCount vs ~1MB for XAML images. The root cause (Glide upscaling stream-based images to display dimensions) is correct, the fix (.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)) is verified to work by Gate, and the test was updated to use a robust comparison approach (comparing resource vs. file image byte counts directly, rather than a hardcoded value).

The prior review (at commit 4a23114) requested changes due to a hardcoded byte count in the test. The author has addressed this — the current test uses Assert.That(resource, Is.EqualTo(file)), which is device-independent. Gate passed with this updated test.

The agent explored 5 alternative fix approaches and could not find a better solution than the PR's fix.

Root Cause

Glide's default behavior when loading from InputStream is to resize the decoded bitmap to match the ImageView's (or display) dimensions. loadImageFromFont in the same file already had .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to prevent this. The two loadImageFromStream overloads were missing this override, causing stream-based images (used by ImageSource.FromResource() and ImageSource.FromStream()) to be upscaled to display resolution (~25MB) rather than preserved at original dimensions (~786KB).

Fix Quality

Approach: Add .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream overloads in PlatformInterop.java.

Assessment: ✅ Correct, minimal (4 lines), and consistent with the existing loadImageFromFont pattern in the same file. The agent tried 5 alternative approaches (all passed tests) but none were simpler or more semantically clear than the PR's approach.

Alternative approaches explored (all passed tests):

  • .centerInside() transformation — prevents upscaling via transformation layer
  • .downsample(DownsampleStrategy.NONE) — disables decode-level upsampling
  • .downsample(DownsampleStrategy.AT_MOST) — prevents upscaling, allows downscaling
  • Read stream to byte[], decode bounds, override explicitly — works but invasive (~60 lines)
  • .downsample(DownsampleStrategy.CENTER_INSIDE) — semantically clear, allows downscaling
  • Downsampler.FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS=false — ❌ FAILED

PR Finalize Review

Title: ✅ Accurate — [Android] Fix excessive memory usage for stream and resource-based image loading

Description: ✅ Good — contains NOTE block, issue details, root cause, description of change, platforms checkbox. Only minor enhancement: add "What NOT to Do" section.

Suggested description addition:

### What NOT to Do (for future agents)
-**Don't use `.dontTransform()`** — Only stops post-decode transformations; the upscaling happens during the decode phase and is not affected
-**Don't use `Downsampler.FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS=false`** — Deep Glide internal; doesn't affect stream-based image decode upscaling path

Code Review Findings

🟡 Medium Issues

1. Test can pass silently if both images fail to load

The test assertion Assert.That(resource, Is.EqualTo(file)) would pass if both labels contain "ByteCount:0" (e.g., if the images fail to load before the button is tapped). The GetBitmapByteCount fallback is also concerning — if the ImageView hasn't rendered yet when the button is tapped, it returns 0 for both, causing a false positive.

Recommendation: Add a guard that the byte count is non-zero:

Assert.That(resource, Is.Not.EqualTo("ByteCount:0"), "Resource image byte count should be non-zero");
Assert.That(resource, Is.EqualTo(file));

2. DownSizeImageAppearProperly.png snapshot changed (unexplained)

The DownSizeImageAppearProperly snapshot was modified by this PR, but the description doesn't explain why. Loading images at SIZE_ORIGINAL instead of display dimensions may change visual appearance if Glide was previously doing beneficial downscaling for this test. The snapshot change should be reviewed to confirm the new appearance is correct.

🟢 Minor Issues

3. Test only covers FromResource path, not FromStream

The test uses ImageSource.FromResource(). Both code paths converge on loadImageFromStream, so one test is sufficient, but a comment would help future contributors understand this:

// ImageSource.FromResource routes through loadImageFromStream in PlatformInterop.java,
// so this test covers both FromResource and FromStream scenarios.

✅ Looks Good

  • Core fix is correct and minimal: 2×2-line change in PlatformInterop.java, consistent with loadImageFromFont pattern
  • Test approach is robust: Comparing resource vs. file byte counts is device-independent
  • AutomationIds are present and matched: HostApp and test correctly reference same IDs
  • NOTE block present in PR description
  • Platform labels accurate (Android only)

Platforms

  • Android (tested by Gate + try-fix)
  • iOS — not affected (fix is Android-only Java code)
  • Windows — not affected
  • macOS — not affected

📋 Expand PR Finalization Review
Title: ✅ Good

Current: [Android] Fix excessive memory usage for stream and resource-based image loading

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

Glide's default behavior for stream-based image loading is to upscale the decoded bitmap to the display dimensions of the target ImageView. This caused ImageSource.FromResource() and ImageSource.FromStream() to produce bitmaps with byte counts proportional to the screen resolution rather than the original image dimensions. File-based loading (loadImageFromFile) and font-based loading (loadImageFromFont) were not affected — loadImageFromFont already used Target.SIZE_ORIGINAL to preserve original dimensions.

Description of Change

Added .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream overloads in PlatformInterop.java:

  • loadImageFromStream(ImageView imageView, InputStream inputStream, ImageLoaderCallback callback)
  • loadImageFromStream(Context context, InputStream inputStream, ImageLoaderCallback callback)

This prevents Glide from upscaling the bitmap to the display size, ensuring stream/resource-loaded images consume memory proportional to their actual dimensions — consistent with the existing behavior for file-based image loading.

Note: Target.SIZE_ORIGINAL also prevents Glide from downsampling very large images. This is the correct behavior for MAUI (matching how file images are loaded), but very large embedded resources will use proportionally more memory.

Key Technical Details

Methods changed (PlatformInterop.java):

  • loadImageFromStream(ImageView, InputStream, ImageLoaderCallback) — previously lacked size override, now uses Target.SIZE_ORIGINAL
  • loadImageFromStream(Context, InputStream, ImageLoaderCallback) — previously lacked size override, now uses Target.SIZE_ORIGINAL

Unchanged (already correct):

  • loadImageFromFont — already used Target.SIZE_ORIGINAL for both ImageView and Context variants
  • loadImageFromFile — file loading was not affected by the upscaling issue

Issues Fixed

Fixes #33239

Platforms Tested

  • Android
  • Windows
  • iOS
  • Mac

Output Screenshot

Before After
33239-BeforeFix 33239-AfterFix
Code Review: ⚠️ Issues Found

Code Review — PR #33590

PR: [Android] Fix excessive memory usage for stream and resource-based image loading
Files reviewed: 4


🔴 Critical Issues

None.


🟡 Moderate Concerns

1. #if ANDROID Inside HostApp Method Bodies

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

Problem: The UI test guidelines say platform-specific logic should be moved to extension methods rather than using inline #if directives inside method bodies. The HostApp file uses #if ANDROID both inside OnMeasureClicked and to guard the GetBitmapByteCount helper method.

// Current — discouraged pattern
private void OnMeasureClicked(object sender, EventArgs e)
{
#if ANDROID
    int resourceByteCount = GetBitmapByteCount(_resourceImage);
    // ...
#endif
}

#if ANDROID
static int GetBitmapByteCount(Image image) { ... }
#endif

Recommendation: Move the Android-specific logic to a platform extension method (e.g., in a Issue33239.android.cs partial file), or at minimum consolidate the #if ANDROID guard to the class/file level rather than inside method bodies.

Severity: Moderate (guideline violation, doesn't affect functionality)


2. Target.SIZE_ORIGINAL Disables All Size Optimization

File: src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java

Problem: Using Target.SIZE_ORIGINAL with Glide prevents both upscaling AND downscaling. This is correct for normal image sizes and matches the pre-existing behavior for loadImageFromFont. However, for very large images loaded via stream/resource (e.g., a multi-megapixel embedded resource), the full-resolution bitmap will be decoded into memory without any size-based downsampling.

// New behavior — loads at original dimensions always (no size cap)
RequestBuilder<Drawable> builder = Glide
    .with(imageView)
    .load(inputStream)
    .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);

Context: The old behavior (upscaling to display dimensions) was arguably worse — a small image was wastefully upscaled. The new behavior is correct for the common case. This concern is primarily about documenting the edge case.

Recommendation: This is acceptable as-is and matches the existing loadImageFromFont pattern. No code change needed, but consider adding a comment noting that SIZE_ORIGINAL intentionally preserves original dimensions for both small and large images.

Severity: Moderate (potential OOM for very large embedded images, but this matches existing loadImageFromFont behavior and is better than the previous upscaling)


🟢 Looks Good

Fix is Correct and Minimal

The core fix — adding .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) to both loadImageFromStream overloads — is exactly the right approach. This matches how loadImageFromFont was already handled and directly addresses the root cause (Glide upscaling stream inputs to display dimensions).

Both Overloads Fixed

Both the ImageView-based and Context-based variants of loadImageFromStream are updated, ensuring consistent behavior regardless of which loading path is used.

Test Approach Is Sound

The Issue33239.cs test compares byte count of a resource-loaded image vs. a file-loaded image using Assert.That(resource, Is.EqualTo(file)). This is a meaningful test since both images are loaded from the same royals.png source — after the fix, both paths should produce the same byte count. This avoids the fragility of asserting an absolute byte count value.

Note on Outdated Review Comment: There is an existing review comment from copilot-pull-request-reviewer suggesting a range-based assertion around a hard-coded value of 786432. This comment is marked as outdated and refers to an earlier version of the test. The current test implementation does not use a hard-coded byte count and does not need this suggestion applied.

Test Class-Level #if ANDROID Guard Is Acceptable

The NUnit test file wraps the entire class in #if ANDROID at the class level (not inside a test method), which is an acceptable pattern for platform-specific tests where the test simply cannot run on other platforms.


@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 18, 2026
@Shalini-Ashokan Shalini-Ashokan changed the title [Android] Fix excessive memory usage for stream-based image loading [Android] Fix excessive memory usage for stream and resource-based image loading Feb 18, 2026
@Shalini-Ashokan
Copy link
Copy Markdown
Contributor Author

The AI summary suggested test did not work. so I updated the test case and verified that it now works as expected.

@rmarinho rmarinho added s/agent-approved AI agent recommends approval - PR fix is correct and optimal and removed s/agent-changes-requested AI agent recommends changes - found a better alternative or issues labels Feb 18, 2026
@kubaflo kubaflo added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad labels Feb 20, 2026
@PureWeen PureWeen changed the base branch from main to inflight/current February 23, 2026 22:03
@PureWeen PureWeen merged commit 1c1d1ca into dotnet:inflight/current Feb 23, 2026
24 of 27 checks passed
github-actions bot pushed a commit that referenced this pull request Feb 24, 2026
…age loading (#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes #33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
jfversluis pushed a commit that referenced this pull request Mar 2, 2026
…age loading (#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes #33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
jfversluis pushed a commit that referenced this pull request Mar 2, 2026
…age loading (#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes #33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
github-actions bot pushed a commit that referenced this pull request Mar 3, 2026
…age loading (#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes #33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
HarishKumarSF4517 pushed a commit to HarishKumarSF4517/maui that referenced this pull request Mar 5, 2026
…age loading (dotnet#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes dotnet#33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
jfversluis pushed a commit that referenced this pull request Mar 6, 2026
… - 1 (#34334)

This PR addresses the UI test image failures that occurred in the
inflight/candidate branch #34294 and
includes updates to improve rendering and test stability across
platforms.

### Controls Handler Registration

* Simplified the logic for registering handlers for controls like
`Label`, `Editor`, `Picker`, `RadioButton`, and `TimePicker` in
`AppHostBuilderExtensions.cs`. The new approach registers all fallback
handlers together, reducing duplicated code and improving
maintainability.

### 
* In the NavigationRootManager class, the line
_rootView.SetTitleBar(null, null); was added in this PR
#34032 by a contributor due to an AI
minor suggestion, but this line causes an issue when swapping pages, so
the TitlebarWorksWhenSwitchingPage test fails. Setting SetTitleBar to
null is already implemented in the WindowHandler class in the
[DisconnectHandler](https://github.com/dotnet/maui/blob/main/src/Core/src/Handlers/Window/WindowHandler.Windows.cs#L55)
method, so I have removed this line _rootView.SetTitleBar(null, null);
from the PR [34032](#34032).

### Image Resave:
* Resaved images: DownSizeImageAppearProperly,
Material3CheckBoxFeatureTests, Material3CheckBox_DefaultAppearance,
DownSizeImageAppearProperly,
VerifyLinearGradientBrushWithStrokeAndOpacity,
VerifyRadialGradientBrushWithOpacity,
VerifyRadialGradientBrushWithShadowAndOpacity,
VerifyLinearGradientBrushWithOpacity,
VerifyLinearGradientBrushWithShadowAndOpacity,
DarkTheme_VerifyVisualState. These PR fixes address the issues:
#33173,
#31567,
#33590,
#34036
* Added the base images for iOS 26, Mac, and Windows.

### Test Stability and Platform-Specific Handling

* Added a platform-specific ignore for a Shell flyout test on iOS 26 due
to a known bug, improving test reliability and clarity about platform
limitations.
* Updated a CollectionView scroll test to wait for specific elements on
Windows, ensuring the test works correctly across platforms.

### DatePicker Handler Tests

* Introduced a helper method `EnsureDialogCreated` in
`DatePickerHandlerTests.Android.cs` to reliably create the native dialog
before reading min/max values, addressing issues caused by lazy dialog
creation after a recent PR. This helper is now used in relevant tests to
improve robustness.
[[1]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R26)
[[2]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R54)
[[3]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R131-R146)
* Clarified the DatePicker test logic in `DatePickerTests.cs` to ensure
the `DateSelected` event fires correctly regardless of dialog state,
improving test reliability on Android.

### Test Case Organization

* Removed the obsolete `VerifyFlyoutPage_IsEnabled` test and renumbered
the remaining FlyoutPage tests in `FlyoutPageFeatureTests.cs` to
maintain sequential order and consistency.
[[1]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L176-R177)
[[2]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L204-R191)
[[3]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L222-R209)
[[4]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L240-R227)
[[5]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L254-R241)
[[6]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L268-R255)
[[7]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L284-R271)
[[8]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L299-R286)
[[9]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L310-R297)
[[10]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L327-R314)
[[11]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L340-R327)
[[12]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L357-R344)
[[13]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L376-R363)
[[14]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L387-R374)
[[15]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L400-R387)
github-actions bot pushed a commit that referenced this pull request Mar 6, 2026
…age loading (#33590)

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

### Issue Details
Stream-based and resource-based image loading consumed excessive memory
on Android versus XAML image loading. Images were loaded at display
dimensions instead of original dimensions, affecting all apps using
embedded resources or streams.

### Root Cause
Glide upscaled stream-based images to display dimensions without size
constraints. XAML had proper size handling, but stream loading lacked
overrides, causing memory to scale with screen size not image size.

### Description of Change
Added size override in PlatformInterop.java to preserve original image
dimensions. This prevents upscaling to display dimensions, making all
loading methods produce consistent memory usage.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [ ] iOS
- [ ] Mac
 
 
### Issues Fixed
  
Fixes #33239 

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="352" height="759" alt="33239-BeforeFix"
src="https://github.com/user-attachments/assets/a1ed4f05-e39a-4d1f-a974-2dc589bf7d78"
/> | <img width="352" height="759" alt="33239-AfterFix"
src="https://github.com/user-attachments/assets/64b067bc-da36-4690-a077-8022ac621223"
/> |
github-actions bot pushed a commit that referenced this pull request Mar 6, 2026
… - 1 (#34334)

This PR addresses the UI test image failures that occurred in the
inflight/candidate branch #34294 and
includes updates to improve rendering and test stability across
platforms.

### Controls Handler Registration

* Simplified the logic for registering handlers for controls like
`Label`, `Editor`, `Picker`, `RadioButton`, and `TimePicker` in
`AppHostBuilderExtensions.cs`. The new approach registers all fallback
handlers together, reducing duplicated code and improving
maintainability.

### 
* In the NavigationRootManager class, the line
_rootView.SetTitleBar(null, null); was added in this PR
#34032 by a contributor due to an AI
minor suggestion, but this line causes an issue when swapping pages, so
the TitlebarWorksWhenSwitchingPage test fails. Setting SetTitleBar to
null is already implemented in the WindowHandler class in the
[DisconnectHandler](https://github.com/dotnet/maui/blob/main/src/Core/src/Handlers/Window/WindowHandler.Windows.cs#L55)
method, so I have removed this line _rootView.SetTitleBar(null, null);
from the PR [34032](#34032).

### Image Resave:
* Resaved images: DownSizeImageAppearProperly,
Material3CheckBoxFeatureTests, Material3CheckBox_DefaultAppearance,
DownSizeImageAppearProperly,
VerifyLinearGradientBrushWithStrokeAndOpacity,
VerifyRadialGradientBrushWithOpacity,
VerifyRadialGradientBrushWithShadowAndOpacity,
VerifyLinearGradientBrushWithOpacity,
VerifyLinearGradientBrushWithShadowAndOpacity,
DarkTheme_VerifyVisualState. These PR fixes address the issues:
#33173,
#31567,
#33590,
#34036
* Added the base images for iOS 26, Mac, and Windows.

### Test Stability and Platform-Specific Handling

* Added a platform-specific ignore for a Shell flyout test on iOS 26 due
to a known bug, improving test reliability and clarity about platform
limitations.
* Updated a CollectionView scroll test to wait for specific elements on
Windows, ensuring the test works correctly across platforms.

### DatePicker Handler Tests

* Introduced a helper method `EnsureDialogCreated` in
`DatePickerHandlerTests.Android.cs` to reliably create the native dialog
before reading min/max values, addressing issues caused by lazy dialog
creation after a recent PR. This helper is now used in relevant tests to
improve robustness.
[[1]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R26)
[[2]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R54)
[[3]](diffhunk://#diff-de28fdea458f311cfcc7e767c7e9e2a4c7c36e4d065ae2ebf2a25b420f183c29R131-R146)
* Clarified the DatePicker test logic in `DatePickerTests.cs` to ensure
the `DateSelected` event fires correctly regardless of dialog state,
improving test reliability on Android.

### Test Case Organization

* Removed the obsolete `VerifyFlyoutPage_IsEnabled` test and renumbered
the remaining FlyoutPage tests in `FlyoutPageFeatureTests.cs` to
maintain sequential order and consistency.
[[1]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L176-R177)
[[2]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L204-R191)
[[3]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L222-R209)
[[4]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L240-R227)
[[5]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L254-R241)
[[6]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L268-R255)
[[7]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L284-R271)
[[8]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L299-R286)
[[9]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L310-R297)
[[10]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L327-R314)
[[11]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L340-R327)
[[12]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L357-R344)
[[13]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L376-R363)
[[14]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L387-R374)
[[15]](diffhunk://#diff-a20c8165e92130c8ebbda3af607c3dd309cf1c1b6c85942abd6ed81132510fb3L400-R387)
PureWeen added a commit that referenced this pull request Mar 11, 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 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
@github-actions github-actions bot locked and limited conversation to collaborators Mar 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-image Image loading, sources, caching 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

Development

Successfully merging this pull request may close these issues.

[Android] Unexpected high Bitmap.ByteCount when loading image via ImageSource.FromResource() or ImageSource.FromStream() in .NET MAUI

7 participants