diff --git a/AUTHORS b/AUTHORS index b5c914b8f1..b5f24fa5f1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,3 +15,4 @@ Alexandre Ardhuin Luke Freeman Vincent Le Quéméner Mike Hoolehan +German Saprykin diff --git a/packages/flutter/lib/src/widgets/scroll_controller.dart b/packages/flutter/lib/src/widgets/scroll_controller.dart index 50476b8f3e..b494312099 100644 --- a/packages/flutter/lib/src/widgets/scroll_controller.dart +++ b/packages/flutter/lib/src/widgets/scroll_controller.dart @@ -323,6 +323,7 @@ class TrackingScrollController extends ScrollController { final Map _positionToListener = {}; ScrollPosition _lastUpdated; + double _lastUpdatedOffset; /// The last [ScrollPosition] to change. Returns null if there aren't any /// attached scroll positions, or there hasn't been any scrolling yet, or the @@ -336,13 +337,16 @@ class TrackingScrollController extends ScrollController { /// /// * [ScrollController.initialScrollOffset], which this overrides. @override - double get initialScrollOffset => _lastUpdated?.pixels ?? super.initialScrollOffset; + double get initialScrollOffset => _lastUpdatedOffset ?? super.initialScrollOffset; @override void attach(ScrollPosition position) { super.attach(position); assert(!_positionToListener.containsKey(position)); - _positionToListener[position] = () { _lastUpdated = position; }; + _positionToListener[position] = () { + _lastUpdated = position; + _lastUpdatedOffset = position.pixels; + }; position.addListener(_positionToListener[position]); } @@ -354,6 +358,8 @@ class TrackingScrollController extends ScrollController { _positionToListener.remove(position); if (_lastUpdated == position) _lastUpdated = null; + if (_positionToListener.isEmpty) + _lastUpdatedOffset = null; } @override diff --git a/packages/flutter/test/widgets/tracking_scroll_controller_test.dart b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart new file mode 100644 index 0000000000..7ebc4050be --- /dev/null +++ b/packages/flutter/test/widgets/tracking_scroll_controller_test.dart @@ -0,0 +1,62 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('TrackingScrollController saves offset', + (WidgetTester tester) async { + final TrackingScrollController controller = new TrackingScrollController(); + final double listItemHeight = 100.0; + + await tester.pumpWidget( + new Directionality( + textDirection: TextDirection.ltr, + child: new PageView.builder( + itemBuilder: (BuildContext context, int index) { + return new ListView( + controller: controller, + children: new List.generate( + 10, + (int i) => new Container( + height: listItemHeight, + child: new Text("Page$index-Item$i")), + ).toList()); + }, + ), + ), + ); + + expect(find.text('Page0-Item1'), findsOneWidget); + expect(find.text('Page1-Item1'), findsNothing); + expect(find.text('Page2-Item0'), findsNothing); + expect(find.text('Page2-Item1'), findsNothing); + + controller.jumpTo(listItemHeight + 10); + await (tester.pumpAndSettle()); + + await tester.fling( + find.text('Page0-Item1'), const Offset(-100.0, 0.0), 10000.0); + await (tester.pumpAndSettle()); + + expect(find.text('Page0-Item1'), findsNothing); + expect(find.text('Page1-Item1'), findsOneWidget); + expect(find.text('Page2-Item0'), findsNothing); + expect(find.text('Page2-Item1'), findsNothing); + + await tester.fling( + find.text('Page1-Item1'), const Offset(-100.0, 0.0), 10000.0); + await (tester.pumpAndSettle()); + + expect(find.text('Page0-Item1'), findsNothing); + expect(find.text('Page1-Item1'), findsNothing); + expect(find.text('Page2-Item0'), findsNothing); + expect(find.text('Page2-Item1'), findsOneWidget); + + await tester.pumpWidget(const Text("Another page")); + + expect(controller.initialScrollOffset, 0.0); + }); +}