diff --git a/lib/widgets/collection/collection_page.dart b/lib/widgets/collection/collection_page.dart index 710b62848..1ca238fd7 100644 --- a/lib/widgets/collection/collection_page.dart +++ b/lib/widgets/collection/collection_page.dart @@ -31,26 +31,26 @@ class _CollectionPageState extends State { @override Widget build(BuildContext context) { return MediaQueryDataProvider( - child: ChangeNotifierProvider.value( - value: collection, - child: Scaffold( - body: WillPopScope( - onWillPop: () { - if (collection.isSelecting) { - collection.browse(); - return SynchronousFuture(false); - } - return SynchronousFuture(true); - }, - child: DoubleBackPopScope( - child: GestureAreaProtectorStack( + child: Scaffold( + body: WillPopScope( + onWillPop: () { + if (collection.isSelecting) { + collection.browse(); + return SynchronousFuture(false); + } + return SynchronousFuture(true); + }, + child: DoubleBackPopScope( + child: GestureAreaProtectorStack( + child: ChangeNotifierProvider.value( + value: collection, child: ThumbnailCollection(), ), ), ), - drawer: AppDrawer(), - resizeToAvoidBottomInset: false, ), + drawer: AppDrawer(), + resizeToAvoidBottomInset: false, ), ); } diff --git a/lib/widgets/collection/thumbnail_collection.dart b/lib/widgets/collection/thumbnail_collection.dart index 292ec7ce4..702195288 100644 --- a/lib/widgets/collection/thumbnail_collection.dart +++ b/lib/widgets/collection/thumbnail_collection.dart @@ -32,21 +32,26 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:provider/provider.dart'; -class ThumbnailCollection extends StatelessWidget { - final ValueNotifier _tileExtentNotifier = ValueNotifier(0); +class ThumbnailCollection extends StatefulWidget { + @override + _ThumbnailCollectionState createState() => _ThumbnailCollectionState(); +} + +class _ThumbnailCollectionState extends State { + TileExtentController _tileExtentController; @override Widget build(BuildContext context) { + _tileExtentController ??= TileExtentController( + settingsRouteKey: context.currentRouteName, + columnCountDefault: 4, + extentMin: 46, + spacing: 0, + ); return SafeArea( bottom: false, child: TileExtentControllerProvider( - controller: TileExtentController( - settingsRouteKey: context.currentRouteName, - extentNotifier: _tileExtentNotifier, - columnCountDefault: 4, - extentMin: 46, - spacing: 0, - ), + controller: _tileExtentController, child: _ThumbnailCollectionContent(), ), ); diff --git a/lib/widgets/common/providers/tile_extent_controller_provider.dart b/lib/widgets/common/providers/tile_extent_controller_provider.dart index 59dd4f31a..0b39401c7 100644 --- a/lib/widgets/common/providers/tile_extent_controller_provider.dart +++ b/lib/widgets/common/providers/tile_extent_controller_provider.dart @@ -15,16 +15,11 @@ class TileExtentControllerProvider extends StatelessWidget { Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { - return MultiProvider( - providers: [ - ProxyProvider0( - update: (_, __) => constraints.biggest, - ), - ProxyProvider( - update: (_, viewportSize, __) => controller..applyTileExtent(viewportSize: viewportSize), - ), - ], - child: child, + return LayoutBuilder( + builder: (context, constraints) => ProxyProvider0( + update: (_, __) => controller..setViewportSize(constraints.biggest), + child: child, + ), ); }, ); diff --git a/lib/widgets/common/scaling.dart b/lib/widgets/common/scaling.dart index eec50a12d..702f5dbc8 100644 --- a/lib/widgets/common/scaling.dart +++ b/lib/widgets/common/scaling.dart @@ -102,9 +102,7 @@ class _GridScaleGestureDetectorState extends State(); final oldExtent = tileExtentController.extentNotifier.value; // sanitize and update grid layout if necessary - final newExtent = tileExtentController.applyTileExtent( - userPreferredExtent: _scaledExtentNotifier.value, - ); + final newExtent = tileExtentController.setUserPreferredExtent(_scaledExtentNotifier.value); _scaledExtentNotifier = null; if (newExtent == oldExtent) { _applyingScale = false; diff --git a/lib/widgets/common/tile_extent_controller.dart b/lib/widgets/common/tile_extent_controller.dart index de0d8ee5d..fa782e058 100644 --- a/lib/widgets/common/tile_extent_controller.dart +++ b/lib/widgets/common/tile_extent_controller.dart @@ -7,7 +7,7 @@ class TileExtentController { final String settingsRouteKey; final int columnCountMin, columnCountDefault; final double spacing, extentMin, extentMax; - final ValueNotifier extentNotifier; + final ValueNotifier extentNotifier = ValueNotifier(0); Size _viewportSize; @@ -15,7 +15,6 @@ class TileExtentController { TileExtentController({ @required this.settingsRouteKey, - @required this.extentNotifier, this.columnCountMin = 2, @required this.columnCountDefault, @required this.extentMin, @@ -23,16 +22,21 @@ class TileExtentController { @required this.spacing, }); - double applyTileExtent({ - Size viewportSize, - double userPreferredExtent = 0, - }) { - if (viewportSize != null) { - // sanitize screen size (useful when reloading while screen is off, reporting a 0,0 size) - final viewportSizeMin = Size.square(extentMin * columnCountMin); - _viewportSize = Size(max(viewportSize.width, viewportSizeMin.width), max(viewportSize.height, viewportSizeMin.height)); + void setViewportSize(Size viewportSize) { + // sanitize screen size (useful when reloading while screen is off, reporting a 0,0 size) + final viewportSizeMin = Size.square(extentMin * columnCountMin); + // dimensions are rounded to prevent updates on minor changes + // 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 + final newViewportSize = Size(max(viewportSize.width, viewportSizeMin.width).roundToDouble(), max(viewportSize.height, viewportSizeMin.height).roundToDouble()); + if (_viewportSize != newViewportSize) { + _viewportSize = newViewportSize; + _update(); } + } + double setUserPreferredExtent(double userPreferredExtent) => _update(userPreferredExtent: userPreferredExtent); + + double _update({double userPreferredExtent = 0}) { final oldUserPreferredExtent = settings.getTileExtent(settingsRouteKey); final currentExtent = extentNotifier.value; final targetExtent = userPreferredExtent > 0 diff --git a/lib/widgets/filter_grids/common/filter_grid_page.dart b/lib/widgets/filter_grids/common/filter_grid_page.dart index 077e03a71..5610731e4 100644 --- a/lib/widgets/filter_grids/common/filter_grid_page.dart +++ b/lib/widgets/filter_grids/common/filter_grid_page.dart @@ -40,9 +40,7 @@ class FilterGridPage extends StatelessWidget { final FilterCallback onTap; final OffsetFilterCallback onLongPress; - final ValueNotifier _tileExtentNotifier = ValueNotifier(0); - - FilterGridPage({ + const FilterGridPage({ Key key, @required this.appBar, @required this.filterSections, @@ -69,7 +67,6 @@ class FilterGridPage extends StatelessWidget { child: TileExtentControllerProvider( controller: TileExtentController( settingsRouteKey: settingsRouteKey ?? context.currentRouteName, - extentNotifier: _tileExtentNotifier, columnCountDefault: 2, extentMin: 60, spacing: 8,