Skip to content

[Android] Implemented material3 support for Label#33599

Merged
jfversluis merged 8 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:material3-label
Mar 1, 2026
Merged

[Android] Implemented material3 support for Label#33599
jfversluis merged 8 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:material3-label

Conversation

@SyedAbdulAzeemSF4852
Copy link
Copy Markdown
Contributor

Description of Change

  • This pull request introduces support for Material3 styling for Label controls on Android by conditionally using a new handler and platform view. The changes ensure that when Material3 is enabled, a new LabelHandler2 and MauiMaterialTextView are used, which properly handle formatted text and layout events. The update also improves event management in the Label control.

Material3 support for Label on Android:

  • Added conditional logic in AppHostBuilderExtensions.cs to use LabelHandler2 with MauiMaterialTextView when Material3 is enabled on Android; otherwise, the default handler is used.
  • Introduced the internal LabelHandler2 class, which overrides CreatePlatformView to return a MauiMaterialTextView.
  • Added the new internal MauiMaterialTextView class, which extends MaterialTextView and optimizes layout event handling for formatted text.

Label control event management improvements:

  • Updated Label.Android.cs to properly attach and detach LayoutChanged event handlers for both MauiTextView and MauiMaterialTextView, preventing memory leaks and ensuring correct event handling.
  • Improved null-checking and early returns in the OnLayoutChanged method for robustness.

Preparatory/cleanup changes:

  • Removed the [ElementHandler<LabelHandler>] attribute from the Label class and replaced it with conditional dependency injection registration. This change was necessary because the static attribute approach cannot support runtime handler selection based on feature flags.

Issues Fixed

Fixes #33598

Output

Material2 Material3

@dotnet-policy-service dotnet-policy-service bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Jan 19, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review January 19, 2026 12:33
Copilot AI review requested due to automatic review settings January 19, 2026 12:33
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 implements Material3 support for the Label control on Android by introducing conditional handler selection and a new Material3-specific platform view. The implementation ensures proper event management and formatted text handling when Material3 is enabled.

Changes:

  • Added runtime-based handler registration that selects LabelHandler2 with MauiMaterialTextView when Material3 is enabled on Android
  • Improved event handling in Label.Android.cs to support both MauiTextView and MauiMaterialTextView with proper cleanup
  • Removed static ElementHandler attribute from Label class to enable dynamic handler selection

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
MauiMaterialTextView.cs New Material3 TextView implementation with optimized layout event handling for formatted text
LabelHandler.Android.cs Added LabelHandler2 that creates Material3 TextView instances
Label.cs Removed static handler attribute to support runtime handler selection
Label.Android.cs Enhanced event management to handle both Material2 and Material3 TextViews
AppHostBuilderExtensions.cs Added conditional handler registration based on Material3 feature flag

@kannanrs
Copy link
Copy Markdown

Request to add usage of all materialstyles with this Implemented like threads...

TIA

@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 17, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionUsed ILabelHandler and improved formatted text comments · ee19ad1

Issue: #33598 - Implement Material3 Support for Label
PR: #33599 - [Android] Implemented material3 support for Label
Platforms Affected: Android only
Files Changed: 5 files (1 new file, 4 modified)

Issue Summary

When UseMaterial3 MSBuild property is enabled, the Label control should use Material3 visual design system on Android. The current implementation does not reflect Material3 behavior — Label should use Material3-specific styling with updated text colors, enhanced formatted text rendering, and appropriate Material3 theme resources.

Files Changed

Fix files:

  • src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs (+12) - Conditional handler registration based on RuntimeFeature.IsMaterial3Enabled
  • src/Controls/src/Core/Label/Label.Android.cs (+36, -11) - Updated handler change logic & event cleanup for both view types
  • src/Controls/src/Core/Label/Label.cs (-1) - Remove [ElementHandler<LabelHandler>] attribute
  • src/Core/src/Handlers/Label/LabelHandler.Android.cs (+9) - New LabelHandler2 class
  • src/Core/src/Platform/Android/Material3Controls/MauiMaterialTextView.cs (+38, new file) - New MauiMaterialTextView extending MaterialTextView

Test files: None

PR Approach

  1. Removes [ElementHandler<LabelHandler>] attribute from Label class (static attribute can't support runtime selection)
  2. Adds MauiMaterialTextView extending MaterialTextView with layout event optimization (only fires for formatted/spannable text)
  3. Adds LabelHandler2 that creates MauiMaterialTextView as platform view
  4. Conditionally registers LabelHandler2 when RuntimeFeature.IsMaterial3Enabled on Android (all other paths use LabelHandler)
  5. Updates Label.Android.cs to handle both MauiTextView and MauiMaterialTextView for LayoutChanged events using DetachLayoutChanged() helper

Reviewer Comments

  • copilot-pull-request-reviewer (resolved): Flagged fragile Java.Lang.String type check in MauiMaterialTextView.SetText(), suggested using Android.Text.SpannableStringNOT addressed by author
  • copilot-pull-request-reviewer (resolved, accepted): Suggested using ILabelHandler pattern match — author accepted this suggestion
  • kannanrs: Requested usage of all material styles similar to other controls — no response from author
  • kubaflo (Feb 17, CHANGES_REQUESTED): "Could you please apply the AI Summary suggestions?" — pending

Disagreements / Edge Cases

File:Line Reviewer Says Author Says Status
MauiMaterialTextView.cs:24 Type check text is not Java.Lang.String is fragile; use Android.Text.ISpanned Not addressed ⚠️ UNRESOLVED
PR comment Use all material styles similar to other controls Not addressed OUT OF SCOPE

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33599 Add LabelHandler2 + MauiMaterialTextView, conditional registration in AppHostBuilderExtensions ⏳ PENDING (Gate) 5 files Original PR

Prior Agent Review

A prior complete agent review exists (posted by rmarinho on Feb 17, 2026, at commit ee19ad1):

  • Gate: ❌ FAILED (no tests exist)
  • Report: REQUEST CHANGES
    No new commits have been pushed since that review.

🚦 Gate — Test Verification
📝 Review SessionUsed ILabelHandler and improved formatted text comments · ee19ad1

Result: ❌ FAILED
Platform: android
Mode: Test Existence Check

Finding

No test files exist for issue #33598 or PR #33599.

Searched:

  • src/Controls/tests/TestCases.HostApp/Issues/ for *33598* or *33599* files
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/ for matching files
  • No references to LabelHandler2, MauiMaterialTextView, or Material3.*Label in any test project

Conclusion

Tests are missing entirely. Cannot verify that tests catch the bug (or validate the fix).
The PR author did not include any UI tests or unit tests with this PR.

Action Required: Tests need to be created. The write-tests-agent can help create them.


🔧 Fix — Analysis & Comparison
📝 Review SessionUsed ILabelHandler and improved formatted text comments · ee19ad1

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33599 Add LabelHandler2 + MauiMaterialTextView, conditional registration ⏳ PENDING (Gate) 5 files Original PR - Gate not passed

Exhausted: N/A (skipped - Gate failed, no tests to run)
Selected Fix: N/A - Gate did not pass


📋 Report — Final Recommendation
📝 Review SessionUsed ILabelHandler and improved formatted text comments · ee19ad1

❌ Final Recommendation: REQUEST CHANGES

Summary

PR #33599 implements Material3 support for the Label control on Android by introducing LabelHandler2 and MauiMaterialTextView. The overall architecture is sound and consistent with how other controls (CollectionView, CarouselView) implement Material3 support. However, the PR is missing tests and has an unaddressed code quality concern flagged by the Copilot reviewer.

Gate Status

Gate ❌ FAILED — No tests exist for issue #33598 or PR #33599. The PR does not include any UI tests or unit tests to verify Material3 Label behavior or catch regressions.

Root Cause (Issue #33598)

When UseMaterial3 is enabled on Android, the Label control was using MauiTextView (extends AppCompatTextView) instead of MaterialTextView. Material3 theming on Android requires MaterialTextView as the base view to properly apply Material3 typography, color roles, and state-layer behaviors. The [ElementHandler<LabelHandler>] static attribute on the Label class also prevented runtime handler selection based on feature flags.

Fix Quality Assessment

Positive aspects:

  • Architecture is sound: LabelHandler2 + MauiMaterialTextView keeps Material3 code isolated from the default path — consistent with how CollectionView implements its Material3 handler
  • Conditional handler registration via RuntimeFeature.IsMaterial3Enabled in AppHostBuilderExtensions.cs is the correct pattern
  • Removing [ElementHandler<LabelHandler>] is correct — CollectionView (which also uses conditional Material3 registration) does NOT use [ElementHandler] either
  • DetachLayoutChanged() helper refactor is good defensive programming that prevents double-subscription and memory leaks
  • Using ILabelHandler pattern match correctly handles both handler types (Copilot suggestion accepted)
  • MauiMaterialContextThemeWrapper.Create(context) reused consistently with other Material3 controls
  • TODO: Material3 - make it public in .net 11 comments show a planned migration path

Issues to address:

  1. Missing tests (blocking): No UI tests or device tests were added. For a feature addition of this magnitude, at minimum an Android UI test demonstrating Material3 Label rendering should be included.

  2. Fragile type check in MauiMaterialTextView.SetText() (should fix): The check _isFormatted = text is not Java.Lang.String is fragile. Any non-Java.Lang.String value is treated as "formatted text," which would incorrectly fire layout events for other ICharSequence implementations that aren't spannable. The Copilot review flagged this and the thread was marked resolved, but the code was NOT changed. Recommend:

    _isFormatted = text is Android.Text.ISpanned;
  3. LayoutChanged event visibility: MauiMaterialTextView.LayoutChanged is internal, but MauiTextView.LayoutChanged is public. If MauiMaterialTextView is made public in .NET 11, this will need to be updated. Consider making it public now to match.

  4. Missing trailing newlines: Both LabelHandler.Android.cs and MauiMaterialTextView.cs are missing trailing newlines (POSIX violation, causes noise in diffs).

Requested Changes

  1. Add tests: Create at minimum an Android UI test for issue Implement Material3 Support for Label #33598:

    • src/Controls/tests/TestCases.HostApp/Issues/Issue33598.cs — ContentPage with Label using formatted text under Material3
    • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33598.cs — NUnit test with [Category(UITestCategories.Label)]
    • The write-tests-agent can help create these
  2. Fix the fragile type check in MauiMaterialTextView.SetText(): Use text is Android.Text.ISpanned instead of text is not Java.Lang.String

  3. Make LayoutChanged event public to match MauiTextView

  4. Add trailing newlines to LabelHandler.Android.cs and MauiMaterialTextView.cs


📋 Expand PR Finalization Review
Title: ✅ Good

Current: [Android] Implemented material3 support for Label

Description: ✅ Good
  • "Implemented" is verbose past-tense. MAUI PR convention uses imperative/noun forms (e.g., "Add", "Fix", "Label:").
  • Could be more specific about what mechanism is used.
    Missing Elements:

** Prepend the required NOTE block at the very top. The rest of the description is good and should be kept as-is.

Recommended action: Add NOTE block, keep existing description content.


Phase 2: Code Review

See code-review.md for full findings.

Summary:

  • 🔴 No critical issues
  • 🟡 2 minor issues (missing newlines at EOF, _isFormatted check explicitness)
  • ✅ Implementation is architecturally sound and consistent with existing Material3 patterns

Verdict

The PR description accurately matches the implementation. The description content is good quality. The only required change is prepending the NOTE block. A new recommended description has been written to recommended-description.md.

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

Description of Change

  • This pull request introduces support for Material3 styling for Label controls on Android by conditionally using a new handler and platform view. The changes ensure that when Material3 is enabled, a new LabelHandler2 and MauiMaterialTextView are used, which properly handle formatted text and layout events. The update also improves event management in the Label control.

Material3 support for Label on Android:

  • Added conditional logic in AppHostBuilderExtensions.cs to use LabelHandler2 with MauiMaterialTextView when Material3 is enabled on Android; otherwise, the default handler is used.
  • Introduced the internal LabelHandler2 class, which overrides CreatePlatformView to return a MauiMaterialTextView.
  • Added the new internal MauiMaterialTextView class, which extends MaterialTextView and optimizes layout event handling for formatted text.

Label control event management improvements:

  • Updated Label.Android.cs to properly attach and detach LayoutChanged event handlers for both MauiTextView and MauiMaterialTextView, preventing memory leaks and ensuring correct event handling.
  • Improved null-checking and early returns in the OnLayoutChanged method for robustness.

Preparatory/cleanup changes:

  • Removed the [ElementHandler] attribute from the Label class and replaced it with conditional dependency injection registration. This change was necessary because the static attribute approach cannot support runtime handler selection based on feature flags.

Issues Fixed

Fixes #33598

Output

Material2 Material3
Code Review: ⚠️ Issues Found

Code Review — PR #33599

Code Review Findings

🔴 Critical Issues

None.


🟡 Suggestions

1. Missing newline at end of file in two files

  • Files: src/Core/src/Handlers/Label/LabelHandler.Android.cs, src/Core/src/Platform/Android/Material3Controls/MauiMaterialTextView.cs
  • Problem: Both diff patches end with \\ No newline at end of file. The .NET MAUI repo expects newlines at end of file per standard C# formatting.
  • Recommendation: Add a trailing newline to both files.

2. _isFormatted type check in MauiMaterialTextView.SetText is fragile

  • File: src/Core/src/Platform/Android/Material3Controls/MauiMaterialTextView.cs (line 24)
  • Problem: The check text is not Java.Lang.String is a negative exclusion. This was flagged in the original Copilot review thread (resolved). While it mirrors the Java PlatformAppCompatTextView behavior exactly (!(text instanceof String)), it's not self-documenting. If a new non-formatted, non-String ICharSequence type were introduced in the future, it could produce false positives.
  • Recommendation: Use a more explicit positive check: text is Android.Text.SpannableString or Android.Text.SpannableStringBuilder or add a comment documenting that the Java implementation uses the same pattern.
// Mirrors PlatformAppCompatTextView.java: !(text instanceof String) means formatted
_isFormatted = text is not Java.Lang.String;

✅ Looks Good

AppHostBuilderExtensions.cs — Conditional DI Registration

  • Using RuntimeFeature.IsMaterial3Enabled at startup for handler selection is consistent with how other Material3 checks work in the codebase (e.g., CheckBoxExtensions.cs, MauiMaterialContextThemeWrapper.cs). Evaluated once at startup, which is the correct place.

Label.Android.csDetachLayoutChanged refactoring

  • Extracting detach logic into a dedicated DetachLayoutChanged() method called at the start of OnHandlerChangedCore is clean and correctly prevents memory leaks when switching handlers.
  • Switching to ILabelHandler pattern match (Handler is not ILabelHandler { PlatformView: var platformView }) addresses the review comment and correctly handles both LabelHandler and LabelHandler2.

LabelHandler2 covariant return type

  • LabelHandler.CreatePlatformView() returns AppCompatTextView. LabelHandler2 overrides it to return MauiMaterialTextView. Since MaterialTextView extends AppCompatTextView, this is a valid C# 9+ covariant return override.

MauiMaterialTextView — Reimplemented vs. OnLayoutFormatted hook

  • MauiTextView extends PlatformAppCompatTextView (Java) which has an onLayoutFormatted hook that only fires for formatted text. MauiMaterialTextView extends MaterialTextView which does not have this hook, so the PR correctly reimplements the same _isFormatted pattern in C#. The implementation is semantically equivalent to the Java version.

[ElementHandler<LabelHandler>] removal from Label.cs

  • Correct approach. The static attribute cannot support runtime selection based on feature flags. The explicit DI registration in AppHostBuilderExtensions.cs correctly covers all platforms: Android with Material3 (LabelHandler2), Android without Material3 (LabelHandler), and all other platforms (LabelHandler).

@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 17, 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.

Could you please apply the AI Summary suggestions?

@rmarinho rmarinho added the s/agent-gate-failed AI could not verify tests catch the bug label Feb 18, 2026
@SyedAbdulAzeemSF4852
Copy link
Copy Markdown
Contributor Author

Could you please apply the AI Summary suggestions?

@kubaflo, I have reviewed the AI summary and implemented the valid suggestions.

@sheiksyedm sheiksyedm added s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation and removed s/agent-fix-implemented PR author implemented the agent suggested fix labels Feb 19, 2026
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Feb 19, 2026

@sheiksyedm thank you for adding the label <3
@SyedAbdulAzeemSF4852 looks good!

@jfversluis jfversluis changed the base branch from main to inflight/current February 27, 2026 18:25
@jfversluis jfversluis added this to the .NET 10 SR5 milestone Feb 27, 2026
@jfversluis jfversluis merged commit dd4c322 into dotnet:inflight/current Mar 1, 2026
30 of 34 checks passed
jfversluis added a commit that referenced this pull request Mar 2, 2026
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes #33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
jfversluis added a commit that referenced this pull request Mar 2, 2026
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes #33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
github-actions bot pushed a commit that referenced this pull request Mar 3, 2026
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes #33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
HarishKumarSF4517 pushed a commit to HarishKumarSF4517/maui that referenced this pull request Mar 5, 2026
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes dotnet#33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
github-actions bot pushed a commit that referenced this pull request Mar 6, 2026
### Description of Change

- This pull request introduces support for Material3 styling for `Label`
controls on Android by conditionally using a new handler and platform
view. The changes ensure that when Material3 is enabled, a new
`LabelHandler2` and `MauiMaterialTextView` are used, which properly
handle formatted text and layout events. The update also improves event
management in the `Label` control.

**Material3 support for Label on Android:**

* Added conditional logic in `AppHostBuilderExtensions.cs` to use
`LabelHandler2` with `MauiMaterialTextView` when Material3 is enabled on
Android; otherwise, the default handler is used.
* Introduced the internal `LabelHandler2` class, which overrides
`CreatePlatformView` to return a `MauiMaterialTextView`.
* Added the new internal `MauiMaterialTextView` class, which extends
`MaterialTextView` and optimizes layout event handling for formatted
text.

**Label control event management improvements:**

* Updated `Label.Android.cs` to properly attach and detach
`LayoutChanged` event handlers for both `MauiTextView` and
`MauiMaterialTextView`, preventing memory leaks and ensuring correct
event handling.
* Improved null-checking and early returns in the `OnLayoutChanged`
method for robustness.

**Preparatory/cleanup changes:**

* Removed the `[ElementHandler<LabelHandler>]` attribute from the Label
class and replaced it with conditional dependency injection
registration. This change was necessary because the static attribute
approach cannot support runtime handler selection based on feature
flags.

### Issues Fixed
Fixes #33598

### Output
| Material2 | Material3 |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/0a5ee29f-ab99-4ea2-b035-351d9a6c409a">
| <img
src="https://github.com/user-attachments/assets/40a6a2a8-3ad1-42a2-913d-17aef86bd624">
|

---------

Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
Co-authored-by: Gerald Versluis <gerald@verslu.is>
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
@kubaflo kubaflo added the s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) label Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-label Label, Span community ✨ Community Contribution material3 partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Material3 Support for Label

9 participants