[Android] Support Android 12+ dynamic wallpaper colors with Material 3
- 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
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