From 1d03459fdbc57f31fab26802e6bc766f15656b8e Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Fri, 16 Aug 2019 13:38:23 -0400 Subject: [PATCH] Fix getOffsetToReveal for growthDirection reversed and AxisDirection down or right (#38441) * Take growth direction into account when computing value for getOffsetForReveal in AxisDirection.right and .up conditions. * Add alignment 1.0 test to left - reverse growth * Add Reverse List showOnScreen test * Formatting fix. --- .../flutter/lib/src/rendering/viewport.dart | 22 ++- .../flutter/test/rendering/viewport_test.dart | 166 ++++++++++++++++++ 2 files changed, 186 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart index a2ebc6a408f..c717df91dfe 100644 --- a/packages/flutter/lib/src/rendering/viewport.dart +++ b/packages/flutter/lib/src/rendering/viewport.dart @@ -649,11 +649,29 @@ abstract class RenderViewportBase('center'); + final Widget centerSliver = SliverPadding( + key: centerKey, + padding: const EdgeInsets.all(22.0), + sliver: SliverToBoxAdapter( + child: Container( + height: 100.0, + child: const Text('Tile center'), + ), + ), + ); + final Widget lowerItem = Container( + height: 100.0, + child: const Text('Tile lower'), + ); + final Widget lowerSliver = SliverPadding( + padding: const EdgeInsets.all(22.0), + sliver: SliverToBoxAdapter( + child: lowerItem, + ), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: Container( + height: 200.0, + width: 300.0, + child: CustomScrollView( + center: centerKey, + reverse: true, + slivers: [lowerSliver, centerSliver], + ), + ), + ), + ), + ); + + final RenderAbstractViewport viewport = tester.allRenderObjects.firstWhere((RenderObject r) => r is RenderAbstractViewport); + + final RenderObject target = tester.renderObject(find.byWidget(lowerItem, skipOffstage: false)); + RevealedOffset revealed = viewport.getOffsetToReveal(target, 0.0); + expect(revealed.offset, - 100 - 22); + + revealed = viewport.getOffsetToReveal(target, 1.0); + expect(revealed.offset, - 100 - 22 - 100); + }); + + testWidgets('Viewport getOffsetToReveal Sliver - left - reverse growth', (WidgetTester tester) async { + const Key centerKey = ValueKey('center'); + final Widget centerSliver = SliverPadding( + key: centerKey, + padding: const EdgeInsets.all(22.0), + sliver: SliverToBoxAdapter( + child: Container( + width: 100.0, + child: const Text('Tile center'), + ), + ), + ); + final Widget lowerItem = Container( + width: 100.0, + child: const Text('Tile lower'), + ); + final Widget lowerSliver = SliverPadding( + padding: const EdgeInsets.all(22.0), + sliver: SliverToBoxAdapter( + child: lowerItem, + ), + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: Container( + height: 200.0, + width: 300.0, + child: CustomScrollView( + scrollDirection: Axis.horizontal, + center: centerKey, + reverse: true, + slivers: [lowerSliver, centerSliver], + ), + ), + ), + ), + ); + + final RenderAbstractViewport viewport = tester.allRenderObjects.firstWhere((RenderObject r) => r is RenderAbstractViewport); + + final RenderObject target = tester.renderObject(find.byWidget(lowerItem, skipOffstage: false)); + RevealedOffset revealed = viewport.getOffsetToReveal(target, 0.0); + expect(revealed.offset, -100 - 22); + + revealed = viewport.getOffsetToReveal(target, 1.0); + expect(revealed.offset, - 100 - 22 - 200); + }); + testWidgets('Viewport getOffsetToReveal Sliver - left', (WidgetTester tester) async { final List children = []; await tester.pumpWidget( @@ -556,6 +657,71 @@ void main() { ); } + testWidgets('Reverse List showOnScreen', (WidgetTester tester) async { + const double screenHeight = 400.0; + const double screenWidth = 400.0; + const double itemHeight = screenHeight / 10.0; + const ValueKey centerKey = ValueKey('center'); + + tester.binding.window.devicePixelRatioTestValue = 1.0; + tester.binding.window.physicalSizeTestValue = const Size(screenWidth, screenHeight); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: CustomScrollView( + center: centerKey, + reverse: true, + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + List.generate( + 10, + (int index) => SizedBox( + height: itemHeight, + child: Text('Item ${-index - 1}'), + ), + ), + ), + ), + SliverList( + key: centerKey, + delegate: SliverChildListDelegate( + List.generate( + 1, + (int index) => const SizedBox( + height: itemHeight, + child: Text('Item 0'), + ), + ), + ), + ), + SliverList( + delegate: SliverChildListDelegate( + List.generate( + 10, + (int index) => SizedBox( + height: itemHeight, + child: Text('Item ${index + 1}'), + ), + ), + ), + ), + ], + ), + ), + ); + + expect(find.text('Item -1'), findsNothing); + + final RenderBox itemNeg1 = + tester.renderObject(find.text('Item -1', skipOffstage: false)); + + itemNeg1.showOnScreen(duration: const Duration(seconds: 1)); + await tester.pumpAndSettle(); + + expect(find.text('Item -1'), findsOneWidget); + }); + testWidgets('in view in inner, but not in outer', (WidgetTester tester) async { final ScrollController inner = ScrollController(); final ScrollController outer = ScrollController();