Skip to content

Add MonochromeFile support for Android adaptive icons#34569

Open
jfversluis wants to merge 2 commits intonet11.0from
feature/android-monochrome-icon
Open

Add MonochromeFile support for Android adaptive icons#34569
jfversluis wants to merge 2 commits intonet11.0from
feature/android-monochrome-icon

Conversation

@jfversluis
Copy link
Copy Markdown
Member

Description

Fixes #22543

Android 13+ supports themed icons with three layers: background, foreground, and monochrome. MAUI currently hardcodes the monochrome layer to always reference the foreground drawable. This causes incorrect rendering when the foreground contains multiple colors — themed icons display the full-color foreground instead of a proper monochrome silhouette.

This PR adds a new MonochromeFile metadata property for MauiIcon, allowing developers to provide a dedicated monochrome image:

<MauiIcon Include="Resources/AppIcon/icon_bg.svg"
          ForegroundFile="Resources/AppIcon/icon_fg.svg"
          MonochromeFile="Resources/AppIcon/icon_mono.svg" />

Behavior

MonochromeFile specified? Monochrome layer Behavior
Yes @mipmap/{name}_monochrome Separate monochrome PNG generated at each density
No @mipmap/{name}_foreground Backwards compatible — existing behavior preserved

Changes

  • ResizeImageInfo.cs — Added MonochromeFilename and MonochromeIsVector properties; parse MonochromeFile metadata from ITaskItem
  • AndroidAdaptiveIconGenerator.cs — Added ProcessMonochrome() method that generates monochrome PNGs at each density; two XML templates (with/without monochrome); removed stale XML caching that prevented incremental updates
  • ResizetizeImagesTests.cs — 3 new tests:
    • AppIconWithMonochromeFileGeneratesMonochromeLayer — verifies monochrome PNGs and XML reference
    • AppIconWithoutMonochromeFileFallsBackToForeground — verifies backwards compatibility
    • AppIconMonochromeLayerHasCorrectSize — verifies density-correct sizing

Testing

  • 571 Resizetizer unit tests pass (3 new + 568 existing, 0 regressions)
  • 20 pre-existing failures in SkiaSharpAppIconToolsTests are unrelated

Android 13+ supports themed icons with a separate monochrome layer.
Previously, MAUI always hardcoded the monochrome layer to reference
the foreground drawable, which causes incorrect rendering when the
foreground contains multiple colors.

Add MonochromeFile metadata to MauiIcon so developers can provide a
dedicated monochrome image for themed icons:

  <MauiIcon Include="icon_bg.svg"
            ForegroundFile="icon_fg.svg"
            MonochromeFile="icon_mono.svg" />

When MonochromeFile is provided:
- A separate _monochrome.png is generated at each density
- The adaptive-icon XML references @mipmap/{name}_monochrome

When MonochromeFile is omitted:
- Backwards compatible: foreground is used as monochrome (existing behavior)

Also removed the early-return cache in ProcessAdaptiveIcon that
prevented the XML from being regenerated when MonochromeFile changed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 19, 2026 13:04
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

🚀 Dogfood this PR with:

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

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

Or

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

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

Adds opt-in support for Android adaptive icon monochrome layers in the Resizetizer pipeline, allowing MAUI apps to provide a dedicated monochrome source image for Android 13+ themed icons while preserving existing behavior when not provided.

Changes:

  • Parse new MonochromeFile metadata into ResizeImageInfo and expose vector detection for it.
  • Generate {name}_monochrome.png at all app icon part densities when MonochromeFile is provided, and emit adaptive icon XML referencing that layer.
  • Add unit tests validating monochrome generation, backward-compatible fallback behavior, and expected output sizing.

Reviewed changes

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

File Description
src/SingleProject/Resizetizer/src/ResizeImageInfo.cs Adds MonochromeFilename/MonochromeIsVector and parses MonochromeFile item metadata.
src/SingleProject/Resizetizer/src/AndroidAdaptiveIconGenerator.cs Generates monochrome app icon part PNGs and updates adaptive icon XML to reference either monochrome or foreground.
src/SingleProject/Resizetizer/test/UnitTests/ResizetizeImagesTests.cs Adds tests for monochrome layer generation, fallback behavior, and size correctness.

You can also share your feedback on Copilot code review. Take the survey.

@jfversluis jfversluis requested a review from mattleibow March 19, 2026 13:11
@jfversluis jfversluis added t/breaking 💥 area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer platform/android labels Mar 19, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

🚨 API change(s) detected @davidortinau FYI

Avoid unnecessary timestamp updates on incremental builds by comparing
file content before writing. This preserves proper incremental build
behavior while still picking up MonochromeFile changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member Author

@jfversluis jfversluis left a comment

Choose a reason for hiding this comment

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

Good catch — replaced the unconditional File.WriteAllText with a WriteFileIfChanged helper that reads existing content first and only writes when it differs. This preserves incremental build timestamps while still picking up changes when MonochromeFile is added/removed. See c0fe91e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-single-project Splash Screen, Multi-Targeting, MauiFont, MauiImage, MauiAsset, Resizetizer platform/android t/breaking 💥

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants