From 619eccd2e37debfca0abf15b2a5a12af7578c4b1 Mon Sep 17 00:00:00 2001 From: gaowanqiu Date: Sat, 29 Aug 2020 07:13:05 +0800 Subject: [PATCH] Fix negative usableCrossAxisExtent in release mode (#64441) --- AUTHORS | 1 + .../lib/src/rendering/sliver_grid.dart | 6 ++- .../flutter/test/widgets/slivers_test.dart | 38 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 97712a36cc..e82132858f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -64,3 +64,4 @@ Brian Wang CaiJingLong Alex Li Ram Navan +meritozh diff --git a/packages/flutter/lib/src/rendering/sliver_grid.dart b/packages/flutter/lib/src/rendering/sliver_grid.dart index f21570d6b7..5470845a6c 100644 --- a/packages/flutter/lib/src/rendering/sliver_grid.dart +++ b/packages/flutter/lib/src/rendering/sliver_grid.dart @@ -326,7 +326,8 @@ class SliverGridDelegateWithFixedCrossAxisCount extends SliverGridDelegate { @override SliverGridLayout getLayout(SliverConstraints constraints) { assert(_debugAssertIsValid()); - final double usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); + final double usableCrossAxisExtent = math.max(0.0, + constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1)); final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; return SliverGridRegularTileLayout( @@ -425,7 +426,8 @@ class SliverGridDelegateWithMaxCrossAxisExtent extends SliverGridDelegate { SliverGridLayout getLayout(SliverConstraints constraints) { assert(_debugAssertIsValid(constraints.crossAxisExtent)); final int crossAxisCount = (constraints.crossAxisExtent / (maxCrossAxisExtent + crossAxisSpacing)).ceil(); - final double usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); + final double usableCrossAxisExtent = math.max(0.0, + constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1)); final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio; return SliverGridRegularTileLayout( diff --git a/packages/flutter/test/widgets/slivers_test.dart b/packages/flutter/test/widgets/slivers_test.dart index c521176698..162686bb0e 100644 --- a/packages/flutter/test/widgets/slivers_test.dart +++ b/packages/flutter/test/widgets/slivers_test.dart @@ -308,6 +308,44 @@ void main() { }, ); + testWidgets( + 'SliverGrid negative usableCrossAxisExtent', + (WidgetTester tester) async { + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 4, + height: 4, + child: CustomScrollView( + slivers: [ + SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + delegate: SliverChildListDelegate( + [ + Container(child: const Center(child: Text('A'))), + Container(child: const Center(child: Text('B'))), + Container(child: const Center(child: Text('C'))), + Container(child: const Center(child: Text('D'))), + ], + ), + ), + ], + ), + ), + ), + ), + ); + + expect(tester.takeException(), isNull); + }, + ); + testWidgets( 'SliverList can handle inaccurate scroll offset due to changes in children list', (WidgetTester tester) async {