Sharpnado.MaterialFrame
A modern MAUI frame component supporting blur, acrylic, dark mode. Implemented with RealtimeBlurView on Android (custom blurview) and UIVisualEffectView on iOS.
Install / Use
/learn @roubachof/Sharpnado.MaterialFrameREADME
Sharpnado.MaterialFrame

Supported platforms
| | |
| - | - |
| <img src="Docs/material_frame_maui.png" height="150"> | <br/><br/> :heavy_check_mark: Android <br/> :heavy_check_mark: iOS <br/> :heavy_check_mark: MacCatalyst <br/> :heavy_check_mark: WinUI |
Initialization
- In
MauiProgram.cs:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseSharpnadoMaterialFrame(loggerEnable: false)
...
}
Version 3.0 - What's New
Version 3.0 brings a complete overhaul of the MaterialFrame architecture with major improvements:
https://github.com/user-attachments/assets/cd1bdeda-9c55-484a-938f-88ef2acbf26a
Handler Migration
All platforms have been migrated from the old Renderer pattern to modern MAUI Handlers:
- Android: ContentViewHandler
- iOS: ContentViewHandler
- MacCatalyst: ContentViewHandler (full support added!)
- Windows: ViewHandler<MaterialFrame, Grid>
Benefits: Better performance, cleaner code, better maintainability, and future-proof architecture.
Android Blur Revolution
Breaking Change: Replaced RenderScript with StackBlur algorithm
Why?
RenderScript was deprecated by Google and completely broken on Android 15+ devices with 16KB page size (crashes on Pixel 8 and newer devices).
The Solution: StackBlur
- Pure C# implementation - No native dependencies, works on ALL Android versions including 15+
- Async background processing - Blur runs on background thread with double buffering
- Change detection - Skips blur when content hasn't changed (0% CPU when static)
- Smooth performance - UI thread blocking reduced from ~22ms to ~3ms
- 60 FPS scrolling - No more frame drops during animations
Performance Metrics
| Metric | Before (RenderScript) | After (StackBlur) | |--------|----------------------|-------------------| | Android 15+ compatibility | 💥 Broken | ✅ Works | | UI thread time | ~22ms | ~3ms | | Static content CPU | 100% | 0% | | Frame rate | 30-45 FPS | 60 FPS | | Blur quality | Excellent | Excellent |
New Features
- MacCatalyst Support: Full blur support on Mac with shared iOS handler
- Better Memory Management: Improved resource cleanup across all platforms
- PropertyMapper: Declarative property handling for better performance
Migration Guide
No breaking changes in the API! Your existing XAML and code will work as-is. The improvements are all under the hood.
The only change: Android now uses StackBlur instead of RenderScript, which means:
- ✅ Works on Android 15+
- ✅ No more crashes on 16KB page size devices
- ✅ Better performance overall
Android Compatibility issues
Warning, because of LayerDrawable the Acrylic glow effect (the white glow on the top of the MaterialFrame is only available on API 23+ (since Marshmallow).
Presentation
The MAUI MaterialFrame delivers out of the box modern popular theming:
- Light
- Dark
- Acrylic
- AcrylicBlur
You can switch from one theme to another thanks to the MaterialTheme property.

MaterialTheme
Light
In light theme, you can set the LightThemeBackgroundColor and control the Elevation.
Dark
In dark theme, you can only control the Elevation, more elevation equals more light on the black frame (see below).
Acrylic
In Acrylic theme, you can still set the LightThemeBackgroundColor, also a Color of F1F1F1 is advised to have a good Acrylic effect.
AcrylicBlur
In AcrylicBlur theme, LightThemeBackgroundColor and Elevation properties are discarded.
You can set the BlurStyle property for both Android and iOS.
REMARK: On Android, the blur uses a pure C# StackBlur implementation that's optimized with async processing and change detection. It's performant but still a CPU operation, so use it wisely.
Light
<img src="Docs/frame_blur_light.png" width="460" />ExtraLight
<img src="Docs/frame_blur_extralight.png" width="460" />Dark
<img src="Docs/frame_blur_dark.png" width="460" />WinUI specific properties
WinUI is the home of the Acrylic effect \o/
WinUIBlurOverlayColor
WinUI only.
Changes the overlay color over the blur (should be a transparent color, obviously). If not set, the different blur style styles take over.
Android specific properties
Because the Android version is a custom blur implementation, you have access to some fine tuning properties.
AndroidBlurOverlayColor
Android only.
Changes the overlay color over the blur (should be a transparent color, obviously). If not set, the different blur style styles take over.
AndroidBlurRadius
Android only.
Changes the blur radius on Android. If set, it takes precedence over MaterialBlurStyle. If not set, the different blur style styles take over.
AndroidBlurRootElement (Performance)
Android only: the root element must be an ancestor of the MaterialFrame.
Blur computation is very costly on Android since it needs to process all the view hierarchy from the root element to be blurred (most of the time the element displaying the underlying image) to the blur frame. The shorter the path, the better the performance. If no root element is set, the activity decor view is used.
Android handler configuration
You can configure the Android handler with static properties:
BlurUpdateIntervalMs
Minimum interval in milliseconds between blur updates. This throttles blur processing to prevent infinite loops and reduce CPU usage.
#if ANDROID
// In MauiProgram.cs or App.xaml.cs
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 16; // 60fps - smoother
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 32; // 30fps - default (balanced)
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 50; // 20fps - battery saver
#endif
Default: 32ms (~30fps) - Good balance between smoothness and battery life
Use cases:
- 16ms (60fps): Smooth animations, gaming scenarios
- 32ms (30fps): General UI, recommended default
- 50ms+ (20fps): Static content, battery-critical apps
BlurProcessingDelayMilliseconds
Delay before starting blur processing after view attachment. Sometimes the computation of the background can take some time (svg images for example). Setting a bigger delay ensures that the background is rendered first and can fix some glitches.
The Android implementation includes:
- StackBlur: Pure C# blur algorithm (no native dependencies)
- Async processing: Blur runs on background thread with double buffering
- Change detection: Skips blur when content hasn't changed (0% CPU when static)
- Time throttling: Configurable update interval prevents infinite loops
- Performance: UI thread blocking reduced from ~22ms to ~3ms
LightThemeBackgroundColor
The background color in Light and Acrylic themes. In Dark theme, this value is ignored because the background color depends on the Elevation.
In AcrylicBlur, the value is discarded cause iOS doesn't allow you to control the overlay color.
Note that setting the BackgroundColor property has no effect with the MaterialFrame.
AcrylicGlowColor
You can change the "glow" of a MaterialFrame with an acrylic theme (the thin top white glow).
Default is white.
This property is ignored is the theme is not set to Acrylic.
Elevation
This property semantic changes according to the theme currently set:
Light Theme
Cast a shadow according to Google's Material elevation specs.
Dark Theme
Change the frame's background color according to Google's dark mode specs:
<img src="Docs/dark_elevation.png" width="460" />Acrylic Theme
Property is ignored and a custom shadow is applied.
AcrylicBlur Theme
Property is ignored, no shadow is cast.
CornerRadius
Sets the corner radius of the frame (default: 5).
Changing theme for every frames
You either use DynamicResource as explained in my previous post.
Or use the static method called ChangeGlobalTheme(Theme newTheme). Setting a new theme on this method will change the MaterialTheme of every MaterialFrame of your app.
Examples of styles
Acrylic style
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sh="clr-namespace:Sharpnado.MaterialFrame;assembly=Sharpnado.MaterialFrame">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml" />
</ResourceDictionaries.MergedDictionaries>
<Style TargetType="sh:MaterialFrame">
<Setter Property="MaterialTheme" Value="Acrylic" />
<Setter Property="Margin" Value="5, 5, 5, 10" />
<Setter Property="Padding" Value="20,15" />
<Setter Property="CornerRadius" Value="10" />
<Setter Property="LightThemeBackgroundColor" Value="{StaticResource AcrylicFrameBackgroundColor}" />
</Style>
</ResourceDictionary>
Colors.xaml file:
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="AcrylicSurface">#E6E6E6</Color>
<Color x:Key="AcrylicFrameBackgroundColor">#F1F1F1</Color>
<Color x:Key="AccentColor">#00E000</Color>
Related Skills
openhue
340.2kControl Philips Hue lights and scenes via the OpenHue CLI.
sag
340.2kElevenLabs text-to-speech with mac-style say UX.
weather
340.2kGet current weather and forecasts via wttr.in or Open-Meteo
tweakcc
1.5kCustomize Claude Code's system prompts, create custom toolsets, input pattern highlighters, themes/thinking verbs/spinners, customize input box & user message styling, support AGENTS.md, unlock private/unreleased features, and much more. Supports both native/npm installs on all platforms.
