From 82f6d43bf19944b610c0d37aca8753533b7dd989 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 13 Dec 2019 14:36:53 -0800 Subject: [PATCH] Avoid NaN for shrinkwrapping viewports (#46265) --- .../flutter/lib/src/rendering/viewport.dart | 16 ++++++- .../test/rendering/viewport_caching_test.dart | 43 +++++++++++++++++++ .../flutter/test/rendering/viewport_test.dart | 35 +++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart index 2498ee6b23..7ce0996dae 100644 --- a/packages/flutter/lib/src/rendering/viewport.dart +++ b/packages/flutter/lib/src/rendering/viewport.dart @@ -505,7 +505,16 @@ abstract class RenderViewportBase= 0.0); assert(crossAxisExtent.isFinite); diff --git a/packages/flutter/test/rendering/viewport_caching_test.dart b/packages/flutter/test/rendering/viewport_caching_test.dart index 7d068d6cc3..3b0b3c9221 100644 --- a/packages/flutter/test/rendering/viewport_caching_test.dart +++ b/packages/flutter/test/rendering/viewport_caching_test.dart @@ -124,4 +124,47 @@ void main() { layout(renderViewport); expect(renderViewport.describeSemanticsClip(null), rectExpandedOnAxis(height * 2.5)); }); + + test('RenderShrinkWrappingViewport describeApproximatePaintClip with infinite viewportMainAxisExtent returns finite rect', () { + final RenderSliver child = CustomConstraintsRenderSliver(const SliverConstraints( + axisDirection: AxisDirection.down, + cacheOrigin: 0.0, + crossAxisDirection: AxisDirection.left, + crossAxisExtent: 400.0, + growthDirection: GrowthDirection.forward, + overlap: 1.0, // must not equal 0 for this test + precedingScrollExtent: 0.0, + remainingPaintExtent: double.infinity, + remainingCacheExtent: 0.0, + scrollOffset: 0.0, + userScrollDirection: ScrollDirection.idle, + viewportMainAxisExtent: double.infinity, // must == infinity + )); + + final RenderShrinkWrappingViewport viewport = RenderShrinkWrappingViewport( + crossAxisDirection: AxisDirection.left, + offset: ViewportOffset.zero(), + children: [ child ], + ); + + layout(viewport); + expect( + viewport.describeApproximatePaintClip(child), + const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0), + ); + }); +} + +class CustomConstraintsRenderSliver extends RenderSliver { + CustomConstraintsRenderSliver(this.constraints); + + @override + SliverGeometry get geometry => const SliverGeometry(); + + @override + final SliverConstraints constraints; + + @override + void performLayout() {} + } diff --git a/packages/flutter/test/rendering/viewport_test.dart b/packages/flutter/test/rendering/viewport_test.dart index 5135c98cc1..3cd59ee45b 100644 --- a/packages/flutter/test/rendering/viewport_test.dart +++ b/packages/flutter/test/rendering/viewport_test.dart @@ -1144,4 +1144,39 @@ void main() { ' its intrinsic dimensions.\n', ); }); + + testWidgets('Handles infinite constraints when TargetPlatform is iOS', (WidgetTester tester) async { + // regression test for https://github.com/flutter/flutter/issues/45866 + final TargetPlatform oldTargetPlatform = debugDefaultTargetPlatformOverride; + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GridView( + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 3, + mainAxisSpacing: 3, + crossAxisSpacing: 3), + children: const [ + Text('a'), + Text('b'), + Text('c'), + ], + ), + ], + ), + ), + ); + + expect(find.text('b'), findsOneWidget); + await tester.drag(find.text('b'), const Offset(0, 200)); + await tester.pumpAndSettle(); + debugDefaultTargetPlatformOverride = oldTargetPlatform; + }); }