From 79146fd0a6071ef06f4187b5843329cf6d09fcd8 Mon Sep 17 00:00:00 2001 From: Kate Lovett Date: Thu, 6 Aug 2020 16:11:16 -0700 Subject: [PATCH] Fix SliverList scrollOffsetCorrection 0 case (#62615) --- .../lib/src/rendering/sliver_list.dart | 18 ++++++++----- .../flutter/test/widgets/slivers_test.dart | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/flutter/lib/src/rendering/sliver_list.dart b/packages/flutter/lib/src/rendering/sliver_list.dart index 5f577b816fa..e47babf7458 100644 --- a/packages/flutter/lib/src/rendering/sliver_list.dart +++ b/packages/flutter/lib/src/rendering/sliver_list.dart @@ -169,20 +169,26 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor { // If the scroll offset is at zero, we should make sure we are // actually at the beginning of the list. if (scrollOffset < precisionErrorTolerance) { - if (indexOf(firstChild) > 0) { + // We iterate from the firstChild in case the leading child has a 0 paint + // extent. + while (indexOf(firstChild) > 0) { final double earliestScrollOffset = childScrollOffset(firstChild); // We correct one child at a time. If there are more children before // the earliestUsefulChild, we will correct it once the scroll offset - // reach zero again. + // reaches zero again. earliestUsefulChild = insertAndLayoutLeadingChild(childConstraints, parentUsesSize: true); assert(earliestUsefulChild != null); final double firstChildScrollOffset = earliestScrollOffset - paintExtentOf(firstChild); - geometry = SliverGeometry( - scrollOffsetCorrection: -firstChildScrollOffset, - ); final SliverMultiBoxAdaptorParentData childParentData = firstChild.parentData as SliverMultiBoxAdaptorParentData; childParentData.layoutOffset = 0.0; - return; + // We only need to correct if the leading child actually has a + // paint extent. + if (firstChildScrollOffset < -precisionErrorTolerance) { + geometry = SliverGeometry( + scrollOffsetCorrection: -firstChildScrollOffset, + ); + return; + } } } diff --git a/packages/flutter/test/widgets/slivers_test.dart b/packages/flutter/test/widgets/slivers_test.dart index b47d651ba55..c521176698a 100644 --- a/packages/flutter/test/widgets/slivers_test.dart +++ b/packages/flutter/test/widgets/slivers_test.dart @@ -814,6 +814,31 @@ void main() { expect(events, equals(['tap'])); }); }); + + testWidgets('SliverList handles 0 scrollOffsetCorrection', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/62198 + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: CustomScrollView( + physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + const [ + SizedBox.shrink(), + Text('index 1'), + Text('index 2'), + ] + ), + ), + ], + ) + ), + )); + await tester.fling(find.byType(Scrollable), const Offset(0.0, -500.0), 10000.0); + await tester.pumpAndSettle(); + expect(tester.takeException(), isNull); + }); } bool isRight(Offset a, Offset b) => b.dx > a.dx;