backdrop filter grouping

This commit is contained in:
Thibault Deckers 2025-02-15 00:01:40 +01:00
parent ae9e2977b4
commit 98537339bd
4 changed files with 37 additions and 34 deletions

View file

@ -180,10 +180,11 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
final EventChannel _errorChannel = const OptionalEventChannel('deckers.thibault/aves/error'); final EventChannel _errorChannel = const OptionalEventChannel('deckers.thibault/aves/error');
// Flutter has various page transition implementations for Android: // Flutter has various page transition implementations for Android:
// - `FadeUpwardsPageTransitionsBuilder` on Oreo / API 27 and below // - `FadeUpwardsPageTransitionsBuilder` on Oreo / Android 8 / API 27 and below
// - `OpenUpwardsPageTransitionsBuilder` on Pie / API 28 // - `OpenUpwardsPageTransitionsBuilder` on Pie / Android 9 / API 28
// - `ZoomPageTransitionsBuilder` on Android 10 / API 29 and above (default in Flutter v3.22.0) // - `ZoomPageTransitionsBuilder` on Q / Android 10 / API 29 (default in Flutter v3.22.0)
// - `PredictiveBackPageTransitionsBuilder` for Android 15 / API 35 intra-app predictive back // - `FadeForwardsPageTransitionsBuilder` on U / Android 14 / API 34
// - `PredictiveBackPageTransitionsBuilder` for Android 15 / API 35 intra-app predictive back (default to `ZoomPageTransitionsBuilder`)
static const _defaultPageTransitionsBuilder = FadeUpwardsPageTransitionsBuilder(); static const _defaultPageTransitionsBuilder = FadeUpwardsPageTransitionsBuilder();
static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator'); static final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator');
static ScreenBrightness? _screenBrightness; static ScreenBrightness? _screenBrightness;

View file

@ -7,8 +7,6 @@ final _filter = ImageFilter.blur(sigmaX: 4, sigmaY: 4);
// as it yields performance issues when there are other layers on top // as it yields performance issues when there are other layers on top
final _identity = ImageFilter.matrix(Matrix4.identity().storage); final _identity = ImageFilter.matrix(Matrix4.identity().storage);
// TODO TLAD [impeller] use `BackdropKey`
class BlurredRect extends StatelessWidget { class BlurredRect extends StatelessWidget {
final bool enabled; final bool enabled;
final Widget child; final Widget child;
@ -22,7 +20,7 @@ class BlurredRect extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipRect( return ClipRect(
child: BackdropFilter( child: BackdropFilter.grouped(
// do not modify tree when disabling filter // do not modify tree when disabling filter
filter: enabled ? _filter : _identity, filter: enabled ? _filter : _identity,
child: child, child: child,
@ -61,7 +59,7 @@ class BlurredRRect extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipRRect( return ClipRRect(
borderRadius: borderRadius ?? BorderRadius.zero, borderRadius: borderRadius ?? BorderRadius.zero,
child: BackdropFilter( child: BackdropFilter.grouped(
// do not modify tree when disabling filter // do not modify tree when disabling filter
filter: enabled ? _filter : _identity, filter: enabled ? _filter : _identity,
child: child, child: child,
@ -83,7 +81,7 @@ class BlurredOval extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipOval( return ClipOval(
child: BackdropFilter( child: BackdropFilter.grouped(
// do not modify tree when disabling filter // do not modify tree when disabling filter
filter: enabled ? _filter : _identity, filter: enabled ? _filter : _identity,
child: child, child: child,

View file

@ -249,12 +249,14 @@ class _GeoMapState extends State<GeoMap> {
child = Column( child = Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
mapHeight != null BackdropGroup(
? SizedBox( child: mapHeight != null
height: mapHeight, ? SizedBox(
child: child, height: mapHeight,
) child: child,
: Expanded(child: child), )
: Expanded(child: child),
),
SafeArea( SafeArea(
top: false, top: false,
bottom: false, bottom: false,

View file

@ -261,27 +261,29 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
return ValueListenableBuilder<bool>( return ValueListenableBuilder<bool>(
valueListenable: _viewLocked, valueListenable: _viewLocked,
builder: (context, locked, child) { builder: (context, locked, child) {
return Stack( return BackdropGroup(
children: [ child: Stack(
child!, children: [
if (!pipEnabled) ...[ child!,
if (locked) ...[ if (!pipEnabled) ...[
const Positioned.fill( if (locked) ...[
child: AbsorbPointer(), const Positioned.fill(
), child: AbsorbPointer(),
Positioned.fill(
child: GestureDetector(
onTap: () => _overlayVisible.value = !_overlayVisible.value,
), ),
), Positioned.fill(
_buildViewerLockedBottomOverlay(), child: GestureDetector(
] else onTap: () => _overlayVisible.value = !_overlayVisible.value,
..._buildOverlays(availableSize).map(_decorateOverlay), ),
const TopGestureAreaProtector(), ),
const SideGestureAreaProtector(), _buildViewerLockedBottomOverlay(),
const BottomGestureAreaProtector(), ] else
..._buildOverlays(availableSize).map(_decorateOverlay),
const TopGestureAreaProtector(),
const SideGestureAreaProtector(),
const BottomGestureAreaProtector(),
],
], ],
], ),
); );
}, },
child: viewer, child: viewer,