rebuild performance review

This commit is contained in:
Thibault Deckers 2021-03-13 11:26:48 +09:00
parent df474a3f66
commit d89907bbc5
6 changed files with 50 additions and 51 deletions

View file

@ -31,26 +31,26 @@ class _CollectionPageState extends State<CollectionPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: ChangeNotifierProvider<CollectionLens>.value( child: Scaffold(
value: collection, body: WillPopScope(
child: Scaffold( onWillPop: () {
body: WillPopScope( if (collection.isSelecting) {
onWillPop: () { collection.browse();
if (collection.isSelecting) { return SynchronousFuture(false);
collection.browse(); }
return SynchronousFuture(false); return SynchronousFuture(true);
} },
return SynchronousFuture(true); child: DoubleBackPopScope(
}, child: GestureAreaProtectorStack(
child: DoubleBackPopScope( child: ChangeNotifierProvider<CollectionLens>.value(
child: GestureAreaProtectorStack( value: collection,
child: ThumbnailCollection(), child: ThumbnailCollection(),
), ),
), ),
), ),
drawer: AppDrawer(),
resizeToAvoidBottomInset: false,
), ),
drawer: AppDrawer(),
resizeToAvoidBottomInset: false,
), ),
); );
} }

View file

@ -32,21 +32,26 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class ThumbnailCollection extends StatelessWidget { class ThumbnailCollection extends StatefulWidget {
final ValueNotifier<double> _tileExtentNotifier = ValueNotifier(0); @override
_ThumbnailCollectionState createState() => _ThumbnailCollectionState();
}
class _ThumbnailCollectionState extends State<ThumbnailCollection> {
TileExtentController _tileExtentController;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_tileExtentController ??= TileExtentController(
settingsRouteKey: context.currentRouteName,
columnCountDefault: 4,
extentMin: 46,
spacing: 0,
);
return SafeArea( return SafeArea(
bottom: false, bottom: false,
child: TileExtentControllerProvider( child: TileExtentControllerProvider(
controller: TileExtentController( controller: _tileExtentController,
settingsRouteKey: context.currentRouteName,
extentNotifier: _tileExtentNotifier,
columnCountDefault: 4,
extentMin: 46,
spacing: 0,
),
child: _ThumbnailCollectionContent(), child: _ThumbnailCollectionContent(),
), ),
); );

View file

@ -15,16 +15,11 @@ class TileExtentControllerProvider extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder( return LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
return MultiProvider( return LayoutBuilder(
providers: [ builder: (context, constraints) => ProxyProvider0<TileExtentController>(
ProxyProvider0( update: (_, __) => controller..setViewportSize(constraints.biggest),
update: (_, __) => constraints.biggest, child: child,
), ),
ProxyProvider<Size, TileExtentController>(
update: (_, viewportSize, __) => controller..applyTileExtent(viewportSize: viewportSize),
),
],
child: child,
); );
}, },
); );

View file

@ -102,9 +102,7 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
final tileExtentController = context.read<TileExtentController>(); final tileExtentController = context.read<TileExtentController>();
final oldExtent = tileExtentController.extentNotifier.value; final oldExtent = tileExtentController.extentNotifier.value;
// sanitize and update grid layout if necessary // sanitize and update grid layout if necessary
final newExtent = tileExtentController.applyTileExtent( final newExtent = tileExtentController.setUserPreferredExtent(_scaledExtentNotifier.value);
userPreferredExtent: _scaledExtentNotifier.value,
);
_scaledExtentNotifier = null; _scaledExtentNotifier = null;
if (newExtent == oldExtent) { if (newExtent == oldExtent) {
_applyingScale = false; _applyingScale = false;

View file

@ -7,7 +7,7 @@ class TileExtentController {
final String settingsRouteKey; final String settingsRouteKey;
final int columnCountMin, columnCountDefault; final int columnCountMin, columnCountDefault;
final double spacing, extentMin, extentMax; final double spacing, extentMin, extentMax;
final ValueNotifier<double> extentNotifier; final ValueNotifier<double> extentNotifier = ValueNotifier(0);
Size _viewportSize; Size _viewportSize;
@ -15,7 +15,6 @@ class TileExtentController {
TileExtentController({ TileExtentController({
@required this.settingsRouteKey, @required this.settingsRouteKey,
@required this.extentNotifier,
this.columnCountMin = 2, this.columnCountMin = 2,
@required this.columnCountDefault, @required this.columnCountDefault,
@required this.extentMin, @required this.extentMin,
@ -23,16 +22,21 @@ class TileExtentController {
@required this.spacing, @required this.spacing,
}); });
double applyTileExtent({ void setViewportSize(Size viewportSize) {
Size viewportSize, // sanitize screen size (useful when reloading while screen is off, reporting a 0,0 size)
double userPreferredExtent = 0, final viewportSizeMin = Size.square(extentMin * columnCountMin);
}) { // dimensions are rounded to prevent updates on minor changes
if (viewportSize != null) { // e.g. available space on S10e is `Size(360.0, 721.0)` when status bar is visible, `Size(360.0, 721.3)` when it is not
// sanitize screen size (useful when reloading while screen is off, reporting a 0,0 size) final newViewportSize = Size(max(viewportSize.width, viewportSizeMin.width).roundToDouble(), max(viewportSize.height, viewportSizeMin.height).roundToDouble());
final viewportSizeMin = Size.square(extentMin * columnCountMin); if (_viewportSize != newViewportSize) {
_viewportSize = Size(max(viewportSize.width, viewportSizeMin.width), max(viewportSize.height, viewportSizeMin.height)); _viewportSize = newViewportSize;
_update();
} }
}
double setUserPreferredExtent(double userPreferredExtent) => _update(userPreferredExtent: userPreferredExtent);
double _update({double userPreferredExtent = 0}) {
final oldUserPreferredExtent = settings.getTileExtent(settingsRouteKey); final oldUserPreferredExtent = settings.getTileExtent(settingsRouteKey);
final currentExtent = extentNotifier.value; final currentExtent = extentNotifier.value;
final targetExtent = userPreferredExtent > 0 final targetExtent = userPreferredExtent > 0

View file

@ -40,9 +40,7 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
final FilterCallback onTap; final FilterCallback onTap;
final OffsetFilterCallback onLongPress; final OffsetFilterCallback onLongPress;
final ValueNotifier<double> _tileExtentNotifier = ValueNotifier(0); const FilterGridPage({
FilterGridPage({
Key key, Key key,
@required this.appBar, @required this.appBar,
@required this.filterSections, @required this.filterSections,
@ -69,7 +67,6 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
child: TileExtentControllerProvider( child: TileExtentControllerProvider(
controller: TileExtentController( controller: TileExtentController(
settingsRouteKey: settingsRouteKey ?? context.currentRouteName, settingsRouteKey: settingsRouteKey ?? context.currentRouteName,
extentNotifier: _tileExtentNotifier,
columnCountDefault: 2, columnCountDefault: 2,
extentMin: 60, extentMin: 60,
spacing: 8, spacing: 8,