Fix tracking scroll controller (#11914)
* Fixed TrackingScrollController cleaning stored offset on position's detach
* Fixed format.
* Fixed format.
* Fixed test with Directionality support.
diff --git a/AUTHORS b/AUTHORS
index b5c914b..b5f24fa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,3 +15,4 @@
Luke Freeman <luke@goposse.com>
Vincent Le Quéméner <eu.lequem@gmail.com>
Mike Hoolehan <mike@hoolehan.com>
+German Saprykin <saprykin.h@gmail.com>
diff --git a/packages/flutter/lib/src/widgets/scroll_controller.dart b/packages/flutter/lib/src/widgets/scroll_controller.dart
index 50476b8..b494312 100644
--- a/packages/flutter/lib/src/widgets/scroll_controller.dart
+++ b/packages/flutter/lib/src/widgets/scroll_controller.dart
@@ -323,6 +323,7 @@
final Map<ScrollPosition, VoidCallback> _positionToListener = <ScrollPosition, VoidCallback>{};
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 @@
///
/// * [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 @@
_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 0000000..7ebc405
--- /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<Widget>.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);
+ });
+}