dotnet / dotnet/maui

[Android] Support Android 12+ dynamic wallpaper colors with Material 3

Open
#36,725 0 comments 2 reactions 0 assignees View on GitHub
area-core-hosting material3 platform/android proposal/open
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

## Description

Material 3 introduces [Dynamic Color](https://m3.material.io/styles/color/dynamic/choosing-a-source), which allows apps to automatically adapt their color scheme based on the user's wallpaper on Android 12+ devices. This creates a personalized, cohesive experience where the app visually integrates with the user's device theme.

When `UseMaterial3` is enabled in .NET MAUI, developers should be able to opt into dynamic wallpaper-based colors so that all M3-themed controls automatically adopt the user's wallpaper-derived palette.

## Current Behavior

MAUI's M3 support uses the **baseline Material 3 theme** (`Theme.Material3.DayNight`) which provides static default colors (purple-neutral palette: `colorPrimary=#6750A4`, `colorSurface=#FFFBFE`, etc.). These colors do not change based on the user's wallpaper or system theme preferences.

## Expected Behavior

When a developer enables dynamic colors:
- On **Android 12+**: All `?attr/color*` theme attributes (`colorPrimary`, `colorSurface`, `colorSecondaryContainer`, etc.) automatically resolve to wallpaper-derived colors
- On **Android < 12**: Graceful fallback to the baseline M3 theme (no-op)
- All MAUI M3 controls (Button, Slider, Switch, Entry, Shell toolbar, bottom nav, etc.) automatically adopt dynamic colors without any per-control changes
- **Dark mode** is respected — dynamic colors provide both light and dark variants

## Proposed API

### Option 1: MSBuild Property (Build-time)

```xml

true
true

```

### Option 2: MauiAppBuilder API (Runtime)

```csharp
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp()
.UseMaterial3(options =>
{
options.UseDynamicColors = true;
});
```

### Option 3: Both (Recommended)

Support both MSBuild property for simple opt-in and builder API for runtime control.

## Implementation Details

### Available APIs

The `Xamarin.Google.Android.Material` binding (v1.14.0) provides the necessary APIs in `Google.Android.Material.Color`:

```csharp
// Apply to all activities in the app
DynamicColors.ApplyToActivitiesIfAvailable(application);

// Apply to a specific activity
DynamicColors.ApplyToActivityIfAvailable(activity);
```

### Integration Point

The `DynamicColors.ApplyToActivitiesIfAvailable()` call should be made in `MauiApplication.OnCreate()` (or equivalent app startup), before any Activity is created. This applies a `ThemeOverlay.Material3.DynamicColors.DayNight` overlay that replaces all M3 color attributes with wallpaper-derived values.

### What Changes Automatically

Once dynamic colors are applied, ALL views using M3 theme attributes automatically get dynamic colors:
- `?attr/colorPrimary` → wallpaper-derived primary
- `?attr/colorSurface` → wallpaper-derived surface
- `?attr/colorSecondaryContainer` → wallpaper-derived container
- All other M3 color tokens (40+ attributes)

No per-control changes needed — the theme overlay handles everything.

### Key Considerations

1. **No custom palette control**: Dynamic colors are entirely wallpaper-driven; developers cannot influence the generated palette
2. **Testing**: Colors vary per device/wallpaper — screenshot tests may need wallpaper mocking
3. **Branding concerns**: Some apps may not want wallpaper colors overriding brand identity — this must be opt-in, never default
4. **Cross-platform**: This is Android-only. iOS and Windows ignore this setting. Developers should be aware of platform-specific behavior

## Visual Reference

| State | Description |
|-------|-------------|
| **Without dynamic colors** | Baseline M3 purple palette (static) |
| **With dynamic colors (blue wallpaper)** | Blue-toned primary, surfaces, containers |
| **With dynamic colors (green wallpaper)** | Green-toned primary, surfaces, containers |
| **Dark mode + dynamic colors** | Dark variants of wallpaper-derived palette |

## References

- [Material 3 Dynamic Color](https://m3.material.io/styles/color/dynamic/choosing-a-source)
- [Android Dynamic Color Guide](https://developer.android.com/develop/ui/views/theming/dynamic-colors)
- [Material Android DynamicColors API](https://developer.android.com/reference/com/google/android/material/color/DynamicColors)
- [Flutter Dynamic Color](https://pub.dev/packages/dynamic_color) — Flutter's approach for reference

Contributor guide

Open the contributing guide

Research direction

Start with the existing Android Material 3 integration and the MauiApplication.OnCreate startup path. Verify the Xamarin.Google.Android.Material v1.14.0 DynamicColors APIs and how UseMaterial3 or its MSBuild property is configured. Done means opt-in dynamic colors apply to Android 12+ M3 controls, older Android versions retain the baseline theme, and light and dark variants work without per-control changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
mobile-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.