Skip to content

Commit eedd85d

Browse files
author
Jean-Marie Alfonsi
committed
fix: issue #32 blur in android ViewHolder
1 parent 841b917 commit eedd85d

17 files changed

+968
-695
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Release Notes v3.0.0
2+
3+
## 🔥 Breaking Changes
4+
5+
### Android: RenderScript → StackBlur
6+
- **Fixed:** Android 15+ crashes on devices with 16KB page size (Pixel 8, Pixel 9, etc.)
7+
- **Changed:** Replaced deprecated RenderScript with pure C# StackBlur algorithm
8+
- **No API changes:** Your existing code works as-is
9+
10+
## ✨ New Features
11+
12+
- **MacCatalyst Support:** Full blur support on macOS
13+
- **Modern Handlers:** Migrated all platforms from Renderers to MAUI Handlers
14+
- **Async Blur:** Background processing with double buffering
15+
- **Change Detection:** Skips blur when content unchanged (0% CPU when static)
16+
17+
## 🚀 Performance
18+
19+
| Metric | Before | After |
20+
|--------|--------|-------|
21+
| Android 15+ | 💥 Crashes | ✅ Works |
22+
| UI thread | ~22ms | ~3ms |
23+
| Static CPU | 100% | 0% |
24+
| Frame rate | 30-45 FPS | 60 FPS |
25+
26+
## 📦 Installation
27+
28+
```bash
29+
dotnet add package Sharpnado.MaterialFrame.Maui --version 3.0.0
30+
```
31+
32+
## 🐛 Bug Fixes
33+
34+
- Fixed Android 15+ compatibility issues
35+
- Eliminated frame drops during scrolling
36+
- Improved memory management and resource cleanup
37+
38+
## 📝 Full Changelog
39+
40+
**Added:**
41+
- MacCatalyst platform support
42+
- StackBlur algorithm for Android
43+
- Async blur processing with double buffering
44+
- Change detection optimization
45+
- Modern MAUI Handlers for all platforms
46+
47+
**Changed:**
48+
- Android blur: RenderScript → StackBlur
49+
- All platforms: Renderers → Handlers
50+
- UI thread blocking: ~22ms → ~3ms
51+
52+
**Fixed:**
53+
- Android 15+ crashes (16KB page size)
54+
- Pixel 8/9 device compatibility
55+
- Frame drops during blur scrolling
56+
- Memory leaks in disposal
57+
58+
**Removed:**
59+
- RenderScript dependency
60+
- Legacy Renderer implementations
61+
- UWP-specific properties
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Release Notes v3.0.1
2+
3+
## 🎯 Android: CollectionView Blur Support
4+
5+
**Platform:** Android only
6+
7+
This release fixes blur functionality in Android CollectionView/RecyclerView scenarios and adds performance tuning capabilities.
8+
9+
**Note:** iOS, MacCatalyst, and Windows are unchanged in this release.
10+
11+
## ✨ New Features
12+
13+
### Android: CollectionView/RecyclerView Blur Support
14+
- **Fixed:** Blur now works correctly when MaterialFrame is inside CollectionView items
15+
- **Solution:** Alpha-based transparency during capture with time-based throttling
16+
- **Use Case:** Product cards, image galleries, chat bubbles with blurred backgrounds
17+
18+
### Configurable Update Interval
19+
```csharp
20+
#if ANDROID
21+
// Adjust blur update frequency
22+
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 16; // 60fps - smoother
23+
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 32; // 30fps - default
24+
AndroidMaterialFrameHandler.BlurUpdateIntervalMs = 50; // 20fps - battery saver
25+
#endif
26+
```
27+
28+
## 🐛 Bug Fixes
29+
30+
- **Fixed:** Blur not working in RecyclerView ViewHolders (sibling view capture issue)
31+
- **Fixed:** Navigation back losing blur root view reference
32+
- **Fixed:** Infinite predraw loops when changing view properties during capture
33+
- **Fixed:** AndroidBlurRootElement causing issues in same-container scenarios
34+
35+
## 🚀 Performance Improvements
36+
37+
| Setting | FPS | Use Case |
38+
|---------|-----|----------|
39+
| 16ms | ~60fps | Smooth animations, gaming |
40+
| 32ms (default) | ~30fps | General use, balanced |
41+
| 50ms | ~20fps | Battery saving |
42+
43+
## 📦 Installation
44+
45+
```bash
46+
dotnet add package Sharpnado.MaterialFrame.Maui --version 3.0.1
47+
```
48+
49+
## 💡 Usage Tips
50+
51+
### CollectionView Best Practices
52+
53+
**❌ Don't use AndroidBlurRootElement in CollectionView items:**
54+
```xml
55+
<CollectionView>
56+
<CollectionView.ItemTemplate>
57+
<Grid x:Name="ItemGrid">
58+
<Image Source="background.png" />
59+
<!-- DON'T: AndroidBlurRootElement="{x:Reference ItemGrid}" -->
60+
<sho:MaterialFrame MaterialTheme="AcrylicBlur" />
61+
</Grid>
62+
</CollectionView.ItemTemplate>
63+
</CollectionView>
64+
```
65+
66+
**✅ Do let blur use default root (activity decor view):**
67+
```xml
68+
<CollectionView>
69+
<CollectionView.ItemTemplate>
70+
<Grid>
71+
<Image Source="background.png" />
72+
<!-- Just omit AndroidBlurRootElement -->
73+
<sho:MaterialFrame MaterialTheme="AcrylicBlur" />
74+
</Grid>
75+
</CollectionView.ItemTemplate>
76+
</CollectionView>
77+
```
78+
79+
## 🔧 Technical Details
80+
81+
### Root View Lifecycle Fix
82+
- `OnDetachedFromWindow` no longer releases root view reference
83+
- Preserves root for navigation back scenarios
84+
- Only releases bitmaps and cancels blur operations on detach
85+
86+
### Alpha Transparency Capture
87+
- Sets parent alpha to 0 during blur capture
88+
- Allows sibling views to be captured without MaterialFrame
89+
- More efficient than visibility changes (no layout recalculation)
90+
91+
### Time-Based Throttling
92+
- Prevents rapid predraw callbacks from alpha/visibility changes
93+
- Default 32ms interval prevents infinite loops
94+
- User-configurable for performance tuning
95+
96+
## 📝 Migration from 3.0.0
97+
98+
No breaking changes - this is a bug fix and feature release.
99+
100+
If you're using `AndroidBlurRootElement` in CollectionView items, remove it for best results.
101+
102+
## 🙏 Credits
103+
104+
Special thanks to the community for reporting the CollectionView blur issue!

Maui.MaterialFrame/Maui.MaterialFrame.csproj

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424

2525
<PropertyGroup>
2626
<Product>$(AssemblyName) ($(TargetFramework))</Product>
27-
<AssemblyVersion>3.0.0</AssemblyVersion>
28-
<AssemblyFileVersion>3.0.0</AssemblyFileVersion>
29-
<Version>3.0.0</Version>
27+
<AssemblyVersion>3.0.1</AssemblyVersion>
28+
<AssemblyFileVersion>3.0.1</AssemblyFileVersion>
29+
<Version>3.0.1</Version>
3030
<PackOnBuild>true</PackOnBuild>
3131
<NeutralLanguage>en</NeutralLanguage>
3232

@@ -45,26 +45,22 @@
4545
<PackageReadmeFile>docs/ReadMe.md</PackageReadmeFile>
4646
<PackageTags>maui android ios winUI netstandard blurview blur UIVisualEffectView acrylic dark mode frame blurred background AcrylicBrush</PackageTags>
4747
<PackageReleaseNotes>
48-
v3.0.0 - Handler Migration and Android Blur Overhaul
48+
v3.0.1 - Android: CollectionView Blur Support and Performance
4949

50-
BREAKING CHANGES:
51-
* Migrated all platforms from Renderers to modern MAUI Handlers
52-
* Android: Replaced RenderScript with StackBlur algorithm (fixes Android 15+ crashes)
50+
ANDROID FIXES:
51+
* Fixed blur not working when MaterialFrame is inside CollectionView/RecyclerView items
52+
* Fixed navigation back issues losing blur root view reference
53+
* Fixed infinite predraw loops with time-based throttling
5354

54-
NEW FEATURES:
55-
* Android: Pure C# StackBlur implementation - works on all Android versions including 15+
56-
* Android: Async background blur processing with double buffering (60 FPS)
57-
* Android: Change detection to skip unnecessary blur processing (0% CPU when static)
58-
* MacCatalyst: Full support with shared iOS handler
55+
NEW ANDROID FEATURES:
56+
* Configurable blur update interval via BlurUpdateIntervalMs static property
57+
* Default 32ms update interval (~30fps) for better battery life
58+
* Users can adjust BlurUpdateIntervalMs for smoothness vs performance tradeoff
59+
* More efficient blur capture using alpha transparency
5960

60-
IMPROVEMENTS:
61-
* All platforms: Modern handler pattern with PropertyMapper
62-
* Android: UI thread blocking reduced from 22ms to 3ms
63-
* Android: Smooth 60 FPS scrolling with blur
64-
* Better memory management and resource cleanup
65-
* Cleaner, more maintainable codebase
61+
Note: This is an Android-only bug fix release. iOS, MacCatalyst, and Windows are unchanged.
6662

67-
See full migration guide: https://github.com/roubachof/Sharpnado.MaterialFrame
63+
See documentation: https://github.com/roubachof/Sharpnado.MaterialFrame
6864
</PackageReleaseNotes>
6965

7066
<Title>A modern MAUI Frame component supporting blur, acrylic, dark mode.</Title>
@@ -107,7 +103,7 @@ public static MauiApp CreateMauiApp()
107103
<EmbedUntrackedSources>true</EmbedUntrackedSources>
108104
<IncludeSymbols>true</IncludeSymbols>
109105
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
110-
<FileVersion>3.0.0</FileVersion>
106+
<FileVersion>3.0.1</FileVersion>
111107
</PropertyGroup>
112108

113109
<ItemGroup>

Maui.MaterialFrame/Platforms/Android/AndroidMaterialFrameHandler.Blur.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ public partial class AndroidMaterialFrameHandler
99
{
1010
private const double StyledBlurRadius = 64;
1111

12-
private static readonly Color DarkBlurOverlayColor = Color.FromArgb("#80000000");
12+
private static readonly Color DarkBlurOverlayColor = Color.FromArgb("#20444444");
1313

1414
private static readonly Color LightBlurOverlayColor = Color.FromArgb("#40FFFFFF");
1515

16-
private static readonly Color ExtraLightBlurOverlayColor = Color.FromArgb("#B0FFFFFF");
16+
private static readonly Color ExtraLightBlurOverlayColor = Color.FromArgb("#60FFFFFF");
1717

18-
private static int _blurAutoUpdateDelayMilliseconds = 20;
19-
private static int _blurProcessingDelayMilliseconds = 10;
18+
private static int _blurAutoUpdateDelayMilliseconds = 16;
19+
private static int _blurProcessingDelayMilliseconds = 4;
2020

2121
private RealtimeBlurView? _realtimeBlurView;
2222

@@ -69,6 +69,30 @@ public static int BlurProcessingDelayMilliseconds
6969
/// </summary>
7070
public static bool ThrowStopExceptionOnDraw { get; set; } = false;
7171

72+
private static int _blurUpdateIntervalMs = 32;
73+
74+
/// <summary>
75+
/// Minimum interval in milliseconds between blur updates.
76+
/// This throttles blur processing to prevent infinite loops and reduce CPU usage.
77+
/// Default is 32ms (~30fps). Lower values = smoother but more CPU intensive.
78+
/// Higher values = better battery life but less smooth updates.
79+
/// </summary>
80+
public static int BlurUpdateIntervalMs
81+
{
82+
get => _blurUpdateIntervalMs;
83+
set
84+
{
85+
if (value < 0)
86+
{
87+
throw new ArgumentException(
88+
"The blur update interval cannot be negative",
89+
nameof(BlurUpdateIntervalMs));
90+
}
91+
92+
_blurUpdateIntervalMs = value;
93+
}
94+
}
95+
7296
private bool IsAndroidBlurPropertySet => MaterialFrame.AndroidBlurRadius > 0;
7397

7498
private double CurrentBlurRadius =>

0 commit comments

Comments
 (0)