perf: prevent expensive blurring when the current page is hidden
This commit is contained in:
parent
25019f8357
commit
512c507942
5 changed files with 95 additions and 51 deletions
|
@ -27,7 +27,7 @@ class SettingsDefaults {
|
||||||
static const mustBackTwiceToExit = true;
|
static const mustBackTwiceToExit = true;
|
||||||
static const keepScreenOn = KeepScreenOn.viewerOnly;
|
static const keepScreenOn = KeepScreenOn.viewerOnly;
|
||||||
static const homePage = HomePageSetting.collection;
|
static const homePage = HomePageSetting.collection;
|
||||||
static const showBottomNavigationBar = false;
|
static const showBottomNavigationBar = true;
|
||||||
static const confirmDeleteForever = true;
|
static const confirmDeleteForever = true;
|
||||||
static const confirmMoveToBin = true;
|
static const confirmMoveToBin = true;
|
||||||
static const confirmMoveUndatedItems = true;
|
static const confirmMoveUndatedItems = true;
|
||||||
|
|
|
@ -44,6 +44,10 @@ class AvesApp extends StatefulWidget {
|
||||||
|
|
||||||
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey(debugLabel: 'app-navigator');
|
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey(debugLabel: 'app-navigator');
|
||||||
|
|
||||||
|
// do not monitor all `ModalRoute`s, which would include popup menus,
|
||||||
|
// so that we can react to fullscreen `PageRoute`s only
|
||||||
|
static final RouteObserver<PageRoute> pageRouteObserver = RouteObserver<PageRoute>();
|
||||||
|
|
||||||
const AvesApp({
|
const AvesApp({
|
||||||
super.key,
|
super.key,
|
||||||
required this.flavor,
|
required this.flavor,
|
||||||
|
@ -62,7 +66,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
|
|
||||||
// observers are not registered when using the same list object with different items
|
// observers are not registered when using the same list object with different items
|
||||||
// the list itself needs to be reassigned
|
// the list itself needs to be reassigned
|
||||||
List<NavigatorObserver> _navigatorObservers = [];
|
List<NavigatorObserver> _navigatorObservers = [AvesApp.pageRouteObserver];
|
||||||
final EventChannel _mediaStoreChangeChannel = const EventChannel('deckers.thibault/aves/media_store_change');
|
final EventChannel _mediaStoreChangeChannel = const EventChannel('deckers.thibault/aves/media_store_change');
|
||||||
final EventChannel _newIntentChannel = const EventChannel('deckers.thibault/aves/intent');
|
final EventChannel _newIntentChannel = const EventChannel('deckers.thibault/aves/intent');
|
||||||
final EventChannel _analysisCompletionChannel = const EventChannel('deckers.thibault/aves/analysis_events');
|
final EventChannel _analysisCompletionChannel = const EventChannel('deckers.thibault/aves/analysis_events');
|
||||||
|
@ -284,6 +288,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
'time_zone': '${now.timeZoneName} (${now.timeZoneOffset})',
|
'time_zone': '${now.timeZoneName} (${now.timeZoneOffset})',
|
||||||
});
|
});
|
||||||
_navigatorObservers = [
|
_navigatorObservers = [
|
||||||
|
AvesApp.pageRouteObserver,
|
||||||
ReportingRouteTracker(),
|
ReportingRouteTracker(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
import 'package:aves/widgets/aves_app.dart';
|
||||||
import 'package:aves/widgets/common/fx/blurred.dart';
|
import 'package:aves/widgets/common/fx/blurred.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -35,9 +36,11 @@ class AvesAppBar extends StatelessWidget {
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
bottom: false,
|
bottom: false,
|
||||||
child: AvesFloatingBar(
|
child: AvesFloatingBar(
|
||||||
builder: (context, backgroundColor) => Material(
|
builder: (context, backgroundColor, child) => Material(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
textStyle: Theme.of(context).appBarTheme.titleTextStyle,
|
textStyle: Theme.of(context).appBarTheme.titleTextStyle,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
@ -69,7 +72,6 @@ class AvesAppBar extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -100,39 +102,75 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
||||||
bool shouldRebuild(covariant _SliverAppBarDelegate oldDelegate) => true;
|
bool shouldRebuild(covariant _SliverAppBarDelegate oldDelegate) => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AvesFloatingBar extends StatelessWidget {
|
class AvesFloatingBar extends StatefulWidget {
|
||||||
final Widget Function(BuildContext context, Color backgroundColor) builder;
|
final Widget Function(BuildContext context, Color backgroundColor, Widget? child) builder;
|
||||||
|
final Widget? child;
|
||||||
|
|
||||||
|
static const margin = EdgeInsets.all(8);
|
||||||
|
static const borderRadius = BorderRadius.all(Radius.circular(8));
|
||||||
|
|
||||||
const AvesFloatingBar({
|
const AvesFloatingBar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.builder,
|
required this.builder,
|
||||||
|
this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
static const margin = EdgeInsets.all(8);
|
@override
|
||||||
static const borderRadius = BorderRadius.all(Radius.circular(8));
|
State<AvesFloatingBar> createState() => _AvesFloatingBarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AvesFloatingBarState extends State<AvesFloatingBar> with RouteAware {
|
||||||
|
// prevent expensive blurring when the current page is hidden
|
||||||
|
final ValueNotifier<bool> _isBlurAllowedNotifier = ValueNotifier(true);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
final route = ModalRoute.of(context);
|
||||||
|
if (route is PageRoute) {
|
||||||
|
AvesApp.pageRouteObserver.subscribe(this, route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
AvesApp.pageRouteObserver.unsubscribe(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPopNext() => _isBlurAllowedNotifier.value = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPushNext() => _isBlurAllowedNotifier.value = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final backgroundColor = theme.appBarTheme.backgroundColor!;
|
final backgroundColor = theme.appBarTheme.backgroundColor!;
|
||||||
final blurred = context.select<Settings, bool>((s) => s.enableOverlayBlurEffect);
|
return ValueListenableBuilder<bool>(
|
||||||
|
valueListenable: _isBlurAllowedNotifier,
|
||||||
|
builder: (context, isBlurAllowed, child) {
|
||||||
|
final blurred = isBlurAllowed && context.select<Settings, bool>((s) => s.enableOverlayBlurEffect);
|
||||||
return Container(
|
return Container(
|
||||||
foregroundDecoration: BoxDecoration(
|
foregroundDecoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: theme.dividerColor,
|
color: theme.dividerColor,
|
||||||
),
|
),
|
||||||
borderRadius: borderRadius,
|
borderRadius: AvesFloatingBar.borderRadius,
|
||||||
),
|
),
|
||||||
margin: margin,
|
margin: AvesFloatingBar.margin,
|
||||||
child: BlurredRRect(
|
child: BlurredRRect(
|
||||||
enabled: blurred,
|
enabled: blurred,
|
||||||
borderRadius: borderRadius,
|
borderRadius: AvesFloatingBar.borderRadius,
|
||||||
child: builder(
|
child: widget.builder(
|
||||||
context,
|
context,
|
||||||
blurred ? backgroundColor.withOpacity(.85) : backgroundColor,
|
blurred ? backgroundColor.withOpacity(.85) : backgroundColor,
|
||||||
|
widget.child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ class _AppBottomNavBarState extends State<AppBottomNavBar> {
|
||||||
];
|
];
|
||||||
|
|
||||||
Widget child = AvesFloatingBar(
|
Widget child = AvesFloatingBar(
|
||||||
builder: (context, backgroundColor) => BottomNavigationBar(
|
builder: (context, backgroundColor, child) => BottomNavigationBar(
|
||||||
items: items
|
items: items
|
||||||
.map((item) => BottomNavigationBarItem(
|
.map((item) => BottomNavigationBarItem(
|
||||||
icon: item.icon(context),
|
icon: item.icon(context),
|
||||||
|
|
|
@ -20,6 +20,7 @@ Future<void> configureAndLaunch() async {
|
||||||
..isErrorReportingAllowed = false
|
..isErrorReportingAllowed = false
|
||||||
..keepScreenOn = KeepScreenOn.always
|
..keepScreenOn = KeepScreenOn.always
|
||||||
..homePage = HomePageSetting.collection
|
..homePage = HomePageSetting.collection
|
||||||
|
..showBottomNavigationBar = true
|
||||||
..setTileExtent(CountryListPage.routeName, 112)
|
..setTileExtent(CountryListPage.routeName, 112)
|
||||||
..setTileLayout(CountryListPage.routeName, TileLayout.grid)
|
..setTileLayout(CountryListPage.routeName, TileLayout.grid)
|
||||||
// collection
|
// collection
|
||||||
|
|
Loading…
Reference in a new issue