@@ -6,17 +6,18 @@ import 'package:flutter/foundation.dart';
66import 'package:flutter/material.dart' ;
77import 'package:flutter_test/flutter_test.dart' ;
88
9- Widget buildTest () {
9+ Widget buildTest ({ ScrollController controller, String title : 'TTTTTTTT' } ) {
1010 return new MediaQuery (
1111 data: const MediaQueryData (),
1212 child: new Scaffold (
1313 body: new DefaultTabController (
1414 length: 4 ,
1515 child: new NestedScrollView (
16+ controller: controller,
1617 headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
1718 return < Widget > [
1819 new SliverAppBar (
19- title: const Text ('TTTTTTTT' ),
20+ title: new Text (title ),
2021 pinned: true ,
2122 expandedHeight: 200.0 ,
2223 forceElevated: innerBoxIsScrolled,
@@ -183,4 +184,108 @@ void main() {
183184 expect (find.text ('ccc1' ), findsOneWidget);
184185 expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
185186 });
186- }
187+
188+ testWidgets ('NestedScrollView with a ScrollController' , (WidgetTester tester) async {
189+ final ScrollController controller = new ScrollController (initialScrollOffset: 50.0 );
190+
191+ double scrollOffset;
192+ controller.addListener (() {
193+ scrollOffset = controller.offset;
194+ });
195+
196+ await tester.pumpWidget (buildTest (controller: controller));
197+ expect (controller.position.minScrollExtent, 0.0 );
198+ expect (controller.position.pixels, 50.0 );
199+ expect (controller.position.maxScrollExtent, 200.0 );
200+
201+ // The appbar's expandedHeight - initialScrollOffset = 150.
202+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 150.0 );
203+
204+ // Fully expand the appbar by scrolling (no animation) to 0.0.
205+ controller.jumpTo (0.0 );
206+ await (tester.pumpAndSettle ());
207+ expect (scrollOffset, 0.0 );
208+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
209+
210+ // Scroll back to 50.0 animating over 100ms.
211+ controller.animateTo (50.0 , duration: const Duration (milliseconds: 100 ), curve: Curves .linear);
212+ await tester.pump ();
213+ await tester.pump ();
214+ expect (scrollOffset, 0.0 );
215+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
216+ await tester.pump (const Duration (milliseconds: 50 )); // 50ms - halfway to scroll offset = 50.0.
217+ expect (scrollOffset, 25.0 );
218+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 175.0 );
219+ await tester.pump (const Duration (milliseconds: 50 )); // 100ms - all the way to scroll offset = 50.0.
220+ expect (scrollOffset, 50.0 );
221+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 150.0 );
222+
223+ // Scroll to the end, (we're not scrolling to the end of the list that contains aaa1,
224+ // just to the end of the outer scrollview). Verify that the first item in each tab
225+ // is still visible.
226+ controller.jumpTo (controller.position.maxScrollExtent);
227+ await tester.pumpAndSettle ();
228+ expect (scrollOffset, 200.0 );
229+ expect (find.text ('aaa1' ), findsOneWidget);
230+
231+ await tester.tap (find.text ('BB' ));
232+ await tester.pumpAndSettle ();
233+ expect (find.text ('bbb1' ), findsOneWidget);
234+
235+ await tester.tap (find.text ('CC' ));
236+ await tester.pumpAndSettle ();
237+ expect (find.text ('ccc1' ), findsOneWidget);
238+
239+ await tester.tap (find.text ('DD' ));
240+ await tester.pumpAndSettle ();
241+ expect (find.text ('ddd1' ), findsOneWidget);
242+ });
243+
244+ testWidgets ('Three NestedScrollViews with one ScrollController' , (WidgetTester tester) async {
245+ final TrackingScrollController controller = new TrackingScrollController ();
246+ expect (controller.mostRecentlyUpdatedPosition, isNull);
247+ expect (controller.initialScrollOffset, 0.0 );
248+
249+ await tester.pumpWidget (
250+ new PageView (
251+ children: < Widget > [
252+ buildTest (controller: controller, title: 'Page0' ),
253+ buildTest (controller: controller, title: 'Page1' ),
254+ buildTest (controller: controller, title: 'Page2' ),
255+ ],
256+ ),
257+ );
258+
259+ // Initially Page0 is visible and Page0's appbar is fully expanded (height = 200.0).
260+ expect (find.text ('Page0' ), findsOneWidget);
261+ expect (find.text ('Page1' ), findsNothing);
262+ expect (find.text ('Page2' ), findsNothing);
263+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
264+
265+ // A scroll collapses Page0's appbar to 150.0.
266+ controller.jumpTo (50.0 );
267+ await (tester.pumpAndSettle ());
268+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 150.0 );
269+
270+ // Fling to Page1. Page1's appbar height is the same as the appbar for Page0.
271+ await tester.fling (find.text ('Page0' ), const Offset (- 100.0 , 0.0 ), 10000.0 );
272+ await (tester.pumpAndSettle ());
273+ expect (find.text ('Page0' ), findsNothing);
274+ expect (find.text ('Page1' ), findsOneWidget);
275+ expect (find.text ('Page2' ), findsNothing);
276+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 150.0 );
277+
278+ // Expand Page1's appbar and then fling to Page2. Page2's appbar appears
279+ // fully expanded.
280+ controller.jumpTo (0.0 );
281+ await (tester.pumpAndSettle ());
282+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
283+ await tester.fling (find.text ('Page1' ), const Offset (- 100.0 , 0.0 ), 10000.0 );
284+ await (tester.pumpAndSettle ());
285+ expect (find.text ('Page0' ), findsNothing);
286+ expect (find.text ('Page1' ), findsNothing);
287+ expect (find.text ('Page2' ), findsOneWidget);
288+ expect (tester.renderObject <RenderBox >(find.byType (AppBar )).size.height, 200.0 );
289+ });
290+
291+ }
0 commit comments