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);
+  });
+}