When a list is scrolling, children can't be tapped (#5222)

diff --git a/examples/flutter_gallery/test/smoke_test.dart b/examples/flutter_gallery/test/smoke_test.dart
index 95f3809..68db1db 100644
--- a/examples/flutter_gallery/test/smoke_test.dart
+++ b/examples/flutter_gallery/test/smoke_test.dart
@@ -43,8 +43,9 @@
 
   await tester.tap(menuItem);
   await tester.pump(); // Launch the demo.
-  await tester
-      .pump(const Duration(seconds: 1)); // Wait until the demo has opened.
+  await tester.pump(const Duration(seconds: 1)); // Wait until the demo has opened.
+
+  expect(find.text('Flutter Gallery'), findsNothing);
 
   // Go back
   if (routeName == '/pesto') {
@@ -64,9 +65,9 @@
 }
 
 void main() {
-  TestWidgetsFlutterBinding binding =
-      TestWidgetsFlutterBinding.ensureInitialized();
-  if (binding is LiveTestWidgetsFlutterBinding) binding.allowAllFrames = true;
+  // TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
+  // if (binding is LiveTestWidgetsFlutterBinding)
+  //   binding.allowAllFrames = true;
 
   testWidgets('Flutter Gallery app smoke test', (WidgetTester tester) async {
     flutter_gallery_main
@@ -87,15 +88,17 @@
       final String routeName = routeNames[i];
       await smokeDemo(tester, routeName);
       await tester.scroll(findGalleryItemByRouteName(tester, routeName), new Offset(0.0, scrollDeltas[i]));
-      await tester.pump();
+      await tester.pump(); // start the scroll
+      await tester.pump(const Duration(milliseconds: 500)); // wait for overscroll to timeout, if necessary
+      await tester.pump(const Duration(milliseconds: 2000)); // wait for overscroll to fade away, if necessary
+      tester.binding.debugAssertNoTransientCallbacks('A transient callback was still active after leaving route $routeName');
     }
 
     Finder navigationMenuButton = findNavigationMenuButton(tester);
     expect(navigationMenuButton, findsOneWidget);
     await tester.tap(navigationMenuButton);
     await tester.pump(); // Start opening drawer.
-    await tester
-        .pump(const Duration(seconds: 1)); // Wait until it's really opened.
+    await tester.pump(const Duration(seconds: 1)); // Wait until it's really opened.
 
     // switch theme
     await tester.tap(find.text('Dark'));
diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart
index b502a49..de61db4 100644
--- a/packages/flutter/lib/src/widgets/scrollable.dart
+++ b/packages/flutter/lib/src/widgets/scrollable.dart
@@ -652,7 +652,10 @@
       key: _gestureDetectorKey,
       gestures: buildGestureDetectors(),
       behavior: HitTestBehavior.opaque,
-      child: buildContent(context)
+      child: new IgnorePointer(
+        ignoring: _controller.isAnimating,
+        child: buildContent(context)
+      )
     );
   }
 
diff --git a/packages/flutter/test/widget/scrollable_fling_test.dart b/packages/flutter/test/widget/scrollable_fling_test.dart
new file mode 100644
index 0000000..3a6829f
--- /dev/null
+++ b/packages/flutter/test/widget/scrollable_fling_test.dart
@@ -0,0 +1,28 @@
+// Copyright 2016 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_test/flutter_test.dart';
+import 'package:flutter/widgets.dart';
+
+void main() {
+  testWidgets('fling and tap', (WidgetTester tester) async {
+    List<String> log = <String>[];
+
+    List<Widget> textWidgets = <Widget>[];
+    for (int i = 0; i < 250; i++)
+      textWidgets.add(new GestureDetector(onTap: () { log.add('tap $i'); }, child: new Text('$i')));
+    await tester.pumpWidget(new Block(children: textWidgets));
+
+    expect(log, equals(<String>[]));
+    await tester.tap(find.byType(Scrollable));
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(log, equals(<String>['tap 18']));
+    await tester.fling(find.byType(Scrollable), new Offset(0.0, -200.0), 1000.0);
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(log, equals(<String>['tap 18']));
+    await tester.tap(find.byType(Scrollable));
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(log, equals(<String>['tap 18']));
+  });
+}