diff --git a/packages/flutter/lib/src/widgets/animated_list.dart b/packages/flutter/lib/src/widgets/animated_list.dart
new file mode 100644
index 0000000..c6bef72
--- /dev/null
+++ b/packages/flutter/lib/src/widgets/animated_list.dart
@@ -0,0 +1,373 @@
+// 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:collection/collection.dart' show binarySearch;
+
+import 'package:flutter/animation.dart';
+import 'package:flutter/foundation.dart';
+
+import 'basic.dart';
+import 'framework.dart';
+import 'scroll_controller.dart';
+import 'scroll_physics.dart';
+import 'scroll_view.dart';
+import 'ticker_provider.dart';
+
+/// Signature for the builder callback used by [AnimatedList].
+typedef Widget AnimatedListItemBuilder(BuildContext context, int index, Animation<double> animation);
+
+/// Signature for the builder callback used by [AnimatedList.remove].
+typedef Widget AnimatedListRemovedItemBuilder(BuildContext context, Animation<double> animation);
+
+// The default insert/remove animation duration.
+const Duration _kDuration = const Duration(milliseconds: 300);
+
+// Incoming and outgoing AnimatedList items.
+class _ActiveItem implements Comparable<_ActiveItem> {
+  _ActiveItem.incoming(this.controller, this.itemIndex) : removedItemBuilder = null;
+  _ActiveItem.outgoing(this.controller, this.itemIndex, this.removedItemBuilder);
+  _ActiveItem.index(this.itemIndex) : controller = null, removedItemBuilder = null;
+
+  final AnimationController controller;
+  final AnimatedListRemovedItemBuilder removedItemBuilder;
+  int itemIndex;
+
+  @override
+  int compareTo(_ActiveItem other) => itemIndex - other.itemIndex;
+}
+
+/// A scrolling container that animates items when they are inserted or removed.
+///
+/// This widget's [AnimatedListState] can be used to dynmically insert or remove
+/// items. To refer to the [AnimatedListState] either provide a [GlobalKey] or
+/// use the static [of] method from an item's input callback.
+///
+/// This widget is similar to one created by [ListView.builder].
+class AnimatedList extends StatefulWidget {
+  /// Creates a scrolling container that animates items when they are inserted or removed.
+  AnimatedList({
+    Key key,
+    @required this.itemBuilder,
+    this.initialItemCount: 0,
+    this.scrollDirection: Axis.vertical,
+    this.reverse: false,
+    this.controller,
+    this.primary,
+    this.physics,
+    this.shrinkWrap: false,
+    this.padding,
+  }) : super(key: key) {
+    assert(itemBuilder != null);
+    assert(initialItemCount != null && initialItemCount >= 0);
+  }
+
+  /// Called, as needed, to build list item widgets.
+  ///
+  /// List items are only built when they're scrolled into view.
+  ///
+  /// The [AnimatedListItemBuilder] index parameter indicates the item's
+  /// posiition in the list. The value of the index parameter will be between 0 and
+  /// [initialItemCount] plus the total number of items that have been inserted
+  /// with [AnimatedListState.insertItem] and less the total number of items
+  /// that have been removed with [AnimatedList.removeItem].
+  ///
+  /// Implementations of this callback should assume that [AnimatedList.removeItem]
+  /// removes an item immediately.
+  final AnimatedListItemBuilder itemBuilder;
+
+  /// The number of items the list will start with.
+  ///
+  /// The appareance of the initial items is not animated. They are
+  /// are created, as needed, by [itemBuilder] with an animation paramter
+  /// of [kAlwaysCompleteAnimation].
+  final int initialItemCount;
+
+  /// The axis along which the scroll view scrolls.
+  ///
+  /// Defaults to [Axis.vertical].
+  final Axis scrollDirection;
+
+  /// Whether the scroll view scrolls in the reading direction.
+  ///
+  /// For example, if the reading direction is left-to-right and
+  /// [scrollDirection] is [Axis.horizontal], then the scroll view scrolls from
+  /// left to right when [reverse] is false and from right to left when
+  /// [reverse] is true.
+  ///
+  /// Similarly, if [scrollDirection] is [Axis.vertical], then the scroll view
+  /// scrolls from top to bottom when [reverse] is false and from bottom to top
+  /// when [reverse] is true.
+  ///
+  /// Defaults to false.
+  final bool reverse;
+
+  /// An object that can be used to control the position to which this scroll
+  /// view is scrolled.
+  ///
+  /// Must be null if [primary] is true.
+  final ScrollController controller;
+
+  /// Whether this is the primary scroll view associated with the parent
+  /// [PrimaryScrollController].
+  ///
+  /// On iOS, this identifies the scroll view that will scroll to top in
+  /// response to a tap in the status bar.
+  ///
+  /// Defaults to true when [scrollDirection] is [Axis.vertical] and
+  /// [controller] is null.
+  final bool primary;
+
+  /// How the scroll view should respond to user input.
+  ///
+  /// For example, determines how the scroll view continues to animate after the
+  /// user stops dragging the scroll view.
+  ///
+  /// Defaults to matching platform conventions.
+  final ScrollPhysics physics;
+
+  /// Whether the extent of the scroll view in the [scrollDirection] should be
+  /// determined by the contents being viewed.
+  ///
+  /// If the scroll view does not shrink wrap, then the scroll view will expand
+  /// to the maximum allowed size in the [scrollDirection]. If the scroll view
+  /// has unbounded constraints in the [scrollDirection], then [shrinkWrap] must
+  /// be true.
+  ///
+  /// Shrink wrapping the content of the scroll view is significantly more
+  /// expensive than expanding to the maximum allowed size because the content
+  /// can expand and contract during scrolling, which means the size of the
+  /// scroll view needs to be recomputed whenever the scroll position changes.
+  ///
+  /// Defaults to false.
+  final bool shrinkWrap;
+
+  /// The amount of space by which to inset the children.
+  final EdgeInsets padding;
+
+  /// The state from the closest instance of this class that encloses the given context.
+  ///
+  /// This method is typically used by [AnimatedList] item widgets that insert or
+  /// remove items in response to user input.
+  ///
+  /// ```dart
+  /// AnimatedListState animatedList = AnimatedList.of(context);
+  /// ```
+  static AnimatedListState of(BuildContext context, { bool nullOk: false }) {
+    assert(nullOk != null);
+    assert(context != null);
+    final AnimatedListState result = context.ancestorStateOfType(const TypeMatcher<AnimatedListState>());
+    if (nullOk || result != null)
+      return result;
+    throw new FlutterError(
+      'AnimatedList.of() called with a context that does not contain a AnimatedList.\n'
+      'No AnimatedList ancestor could be found starting from the context that was passed to AnimatedList.of(). '
+      'This can happen when the context provided is from the same StatefulWidget that '
+      'built the AnimatedList. Please see the AnimatedList documentation for examples '
+      'of how to refer to an AnimatedListState object: '
+      '  https://docs.flutter.io/flutter/widgets/AnimatedState-class.html\n'
+      'The context used was:\n'
+      '  $context'
+    );
+  }
+
+  @override
+  AnimatedListState createState() => new AnimatedListState();
+}
+
+/// The state for a scrolling container that animates items when they are
+/// inserted or removed.
+///
+/// When an item is inserted with [insertItem] an animation begins running.
+/// The animation is passed to [itemBuilder] whenever the item's widget
+/// is needed.
+///
+/// When an item is removed with [removeItem] its animation is reversed.
+/// The removed item's animation  is passed to the [removeItem] builder
+/// parameter.
+///
+/// An app that needs to insert or remove items in response to an event
+/// can refer to the [AnimatedList]'s state with a global key:
+///
+/// ```dart
+/// GlobalKey<AnimatedListState> listKey = new GlobalKey<AnimatedListState>();
+/// ...
+/// new AnimatedList(key: listKey, ...);
+/// ...
+/// listKey.currentState.insert(123);
+/// ```
+///
+/// AnimatedList item input handlers can also refer to their [AnimatedListState]
+/// with the static [of] method.
+class AnimatedListState extends State<AnimatedList> with TickerProviderStateMixin {
+  final List<_ActiveItem> _incomingItems = <_ActiveItem>[];
+  final List<_ActiveItem> _outgoingItems = <_ActiveItem>[];
+  int _itemsCount = 0;
+
+  @override
+  void initState() {
+    super.initState();
+    _itemsCount = widget.initialItemCount;
+  }
+
+  @override
+  void dispose() {
+    for (_ActiveItem item in _incomingItems)
+      item.controller.dispose();
+    for (_ActiveItem item in _outgoingItems)
+      item.controller.dispose();
+    super.dispose();
+  }
+
+  _ActiveItem _removeActiveItemAt(List<_ActiveItem> items, int itemIndex) {
+    final int i = binarySearch(items, new _ActiveItem.index(itemIndex));
+    return i == -1 ? null : items.removeAt(i);
+  }
+
+  _ActiveItem _activeItemAt(List<_ActiveItem> items, int itemIndex) {
+    final int i = binarySearch(items, new _ActiveItem.index(itemIndex));
+    return i == -1 ? null : items[i];
+  }
+
+  // The insertItem() and removeItem() index parameters are defined as if the
+  // removeItem() operation removed the corresponding list entry immediately.
+  // The entry is only actually removed from the ListView when the remove animation
+  // finishes. The entry is added to _outgoingItems when removeItem is called
+  // and removed from _outgoingItems when the remove animation finishes.
+
+  int _indexToItemIndex(int index) {
+    int itemIndex = index;
+    for (_ActiveItem item in _outgoingItems) {
+      if (item.itemIndex <= itemIndex)
+        itemIndex += 1;
+      else
+        break;
+    }
+    return itemIndex;
+  }
+
+  int _itemIndexToIndex(int itemIndex) {
+    int index = itemIndex;
+    for (_ActiveItem item in _outgoingItems) {
+      assert(item.itemIndex != itemIndex);
+      if (item.itemIndex < itemIndex)
+        index -= 1;
+      else
+        break;
+    }
+    return index;
+  }
+
+  /// Insert an item at [index] and start an animation that will be passed
+  /// to [itemBuilder] when the item is visible.
+  ///
+  /// This method's semantics are the same as Dart's [List.insert] method:
+  /// it increases the length of the list by one and shifts all items at or
+  /// after [index] towards the end of the list.
+  void insertItem(int index, { Duration duration: _kDuration }) {
+    assert(index != null && index >= 0);
+    assert(duration != null);
+
+    final int itemIndex = _indexToItemIndex(index);
+    assert(itemIndex >= 0 && itemIndex <= _itemsCount);
+
+    // Increment the incoming and outgoing item indices to account
+    // for the insertion.
+    for (_ActiveItem item in _incomingItems) {
+      if (item.itemIndex >= itemIndex)
+        item.itemIndex += 1;
+    }
+    for (_ActiveItem item in _outgoingItems) {
+      if (item.itemIndex >= itemIndex)
+        item.itemIndex += 1;
+    }
+
+    final AnimationController controller = new AnimationController(duration: duration, vsync: this);
+    final _ActiveItem incomingItem = new _ActiveItem.incoming(controller, itemIndex);
+    setState(() {
+      _incomingItems
+        ..add(incomingItem)
+        ..sort();
+      _itemsCount += 1;
+    });
+
+    controller.forward().then((Null value) {
+      _removeActiveItemAt(_incomingItems, incomingItem.itemIndex).controller.dispose();
+    });
+  }
+
+  /// Remove the item at [index] and start an animation that will be passed
+  /// to [builder] when the item is visible.
+  ///
+  /// Items are removed immediately. After an item has been removed, its index
+  /// will no longer be passed to the [itemBuilder]. However the item will still
+  /// appear in the list for [duration] and during that time [builder] must
+  /// construct its widget as needed.
+  ///
+  /// This method's semantics are the same as Dart's [List.remove] method:
+  /// it decreases the length of the list by one and shifts all items at or
+  /// before [index] towards the beginning of the list.
+  void removeItem(int index, AnimatedListRemovedItemBuilder builder, { Duration duration: _kDuration }) {
+    assert(index != null && index >= 0);
+    assert(builder != null);
+    assert(duration != null);
+
+    final int itemIndex = _indexToItemIndex(index);
+    assert(itemIndex >= 0 && itemIndex < _itemsCount);
+    assert(_activeItemAt(_outgoingItems, itemIndex) == null);
+
+    final _ActiveItem incomingItem = _removeActiveItemAt(_incomingItems, itemIndex);
+    final AnimationController controller = incomingItem?.controller
+      ?? new AnimationController(duration: duration, value: 1.0, vsync: this);
+    final _ActiveItem outgoingItem = new _ActiveItem.outgoing(controller, itemIndex, builder);
+    setState(() {
+      _outgoingItems
+        ..add(outgoingItem)
+        ..sort();
+    });
+
+    controller.reverse().then((Null value) {
+      _removeActiveItemAt(_outgoingItems, outgoingItem.itemIndex).controller.dispose();
+
+      // Decrement the incoming and outgoing item indices to account
+      // for the removal.
+      for (_ActiveItem item in _incomingItems) {
+        if (item.itemIndex > outgoingItem.itemIndex)
+          item.itemIndex -= 1;
+      }
+      for (_ActiveItem item in _outgoingItems) {
+        if (item.itemIndex > outgoingItem.itemIndex)
+          item.itemIndex -= 1;
+      }
+
+      setState(() {
+        _itemsCount -= 1;
+      });
+    });
+  }
+
+  Widget _itemBuilder(BuildContext context, int itemIndex) {
+    final _ActiveItem outgoingItem = _activeItemAt(_outgoingItems, itemIndex);
+    if (outgoingItem != null)
+      return outgoingItem.removedItemBuilder(context, outgoingItem.controller.view);
+
+    final _ActiveItem incomingItem = _activeItemAt(_incomingItems, itemIndex);
+    final Animation<double> animation = incomingItem?.controller?.view ?? kAlwaysCompleteAnimation;
+    return widget.itemBuilder(context, _itemIndexToIndex(itemIndex), animation);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return new ListView.builder(
+      itemBuilder: _itemBuilder,
+      itemCount: _itemsCount,
+      scrollDirection: widget.scrollDirection,
+      reverse: widget.reverse,
+      controller: widget.controller,
+      primary: widget.primary,
+      physics: widget.physics,
+      shrinkWrap: widget.shrinkWrap,
+      padding: widget.padding,
+    );
+  }
+}
diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart
index 5c7020a..cf75d3e 100644
--- a/packages/flutter/lib/widgets.dart
+++ b/packages/flutter/lib/widgets.dart
@@ -10,6 +10,7 @@
 export 'package:vector_math/vector_math_64.dart' show Matrix4;
 
 export 'src/widgets/animated_cross_fade.dart';
+export 'src/widgets/animated_list.dart';
 export 'src/widgets/animated_size.dart';
 export 'src/widgets/app.dart';
 export 'src/widgets/async.dart';
diff --git a/packages/flutter/test/widgets/animated_list_test.dart b/packages/flutter/test/widgets/animated_list_test.dart
new file mode 100644
index 0000000..1193a48
--- /dev/null
+++ b/packages/flutter/test/widgets/animated_list_test.dart
@@ -0,0 +1,176 @@
+// 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_test/flutter_test.dart';
+import 'package:flutter/widgets.dart';
+
+void main() {
+  testWidgets('AnimatedList initialItemCount', (WidgetTester tester) async {
+    final Map<int, Animation<double>> animations = <int, Animation<double>>{};
+
+    await tester.pumpWidget(
+      new AnimatedList(
+        initialItemCount: 2,
+        itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+          animations[index] = animation;
+          return new SizedBox(
+            height: 100.0,
+            child: new Center(
+              child: new Text('item $index'),
+            ),
+          );
+        },
+      ),
+    );
+
+    expect(find.text('item 0'), findsOneWidget);
+    expect(find.text('item 1'), findsOneWidget);
+    expect(animations.containsKey(0), true);
+    expect(animations.containsKey(1), true);
+    expect(animations[0].value, 1.0);
+    expect(animations[1].value, 1.0);
+  });
+
+  testWidgets('AnimatedList insert', (WidgetTester tester) async {
+    final GlobalKey<AnimatedListState> listKey = new GlobalKey<AnimatedListState>();
+
+    await tester.pumpWidget(
+      new AnimatedList(
+        key: listKey,
+        itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+          return new SizeTransition(
+            key: new ValueKey<int>(index),
+            axis: Axis.vertical,
+            sizeFactor: animation,
+            child: new SizedBox(
+              height: 100.0,
+              child: new Center(
+                child: new Text('item $index'),
+              ),
+            ),
+          );
+        },
+      ),
+    );
+
+    double itemHeight(int index) => tester.getSize(find.byKey(new ValueKey<int>(index))).height;
+    double itemTop(int index) => tester.getTopLeft(find.byKey(new ValueKey<int>(index))).dy;
+    double itemBottom(int index) => tester.getBottomLeft(find.byKey(new ValueKey<int>(index))).dy;
+
+    listKey.currentState.insertItem(0, duration: const Duration(milliseconds: 100));
+    await tester.pump();
+
+    // Newly inserted item 0's height should animate from 0 to 100
+    expect(itemHeight(0), 0.0);
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(itemHeight(0), 50.0);
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(itemHeight(0), 100.0);
+
+    // The list now contains one fully expanded item at the top:
+    expect(find.text('item 0'), findsOneWidget);
+    expect(itemTop(0), 0.0);
+    expect(itemBottom(0), 100.0);
+
+    listKey.currentState.insertItem(0, duration: const Duration(milliseconds: 100));
+    listKey.currentState.insertItem(0, duration: const Duration(milliseconds: 100));
+    await tester.pump();
+
+    // The height of the newly inserted items at index 0 and 1 should animate from 0 to 100.
+    // The height of the original item, now at index 2, should remain 100.
+    expect(itemHeight(0), 0.0);
+    expect(itemHeight(1), 0.0);
+    expect(itemHeight(2), 100.0);
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(itemHeight(0), 50.0);
+    expect(itemHeight(1), 50.0);
+    expect(itemHeight(2), 100.0);
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(itemHeight(0), 100.0);
+    expect(itemHeight(1), 100.0);
+    expect(itemHeight(2), 100.0);
+
+    // The newly inserted "item 1" and "item 2" appear above "item 0"
+    expect(find.text('item 0'), findsOneWidget);
+    expect(find.text('item 1'), findsOneWidget);
+    expect(find.text('item 2'), findsOneWidget);
+    expect(itemTop(0), 0.0);
+    expect(itemBottom(0), 100.0);
+    expect(itemTop(1), 100.0);
+    expect(itemBottom(1), 200.0);
+    expect(itemTop(2), 200.0);
+    expect(itemBottom(2), 300.0);
+  });
+
+  testWidgets('AnimatedList remove', (WidgetTester tester) async {
+    final GlobalKey<AnimatedListState> listKey = new GlobalKey<AnimatedListState>();
+    final List<int> items = <int>[0, 1, 2];
+
+    Widget buildItem(BuildContext context, int item, Animation<double> animation) {
+      return new SizeTransition(
+        key: new ValueKey<int>(item),
+        axis: Axis.vertical,
+        sizeFactor: animation,
+        child: new SizedBox(
+          height: 100.0,
+          child: new Center(
+            child: new Text('item $item'),
+          ),
+        ),
+      );
+    }
+
+    await tester.pumpWidget(
+      new AnimatedList(
+        key: listKey,
+        initialItemCount: 3,
+        itemBuilder: (BuildContext context, int index, Animation<double> animation) {
+          return buildItem(context, items[index], animation);
+        },
+      ),
+    );
+
+    double itemTop(int index) => tester.getTopLeft(find.byKey(new ValueKey<int>(index))).dy;
+    double itemBottom(int index) => tester.getBottomLeft(find.byKey(new ValueKey<int>(index))).dy;
+
+    expect(find.text('item 0'), findsOneWidget);
+    expect(find.text('item 1'), findsOneWidget);
+    expect(find.text('item 2'), findsOneWidget);
+
+    items.removeAt(0);
+    listKey.currentState.removeItem(0,
+      (BuildContext context, Animation<double> animation) => buildItem(context, 0, animation),
+      duration: const Duration(milliseconds: 100),
+    );
+
+    // Item's 0, 1, 2 at 0, 100, 200. All heights 100.
+    expect(itemTop(0), 0.0);
+    expect(itemBottom(0), 100.0);
+    expect(itemTop(1), 100.0);
+    expect(itemBottom(1), 200.0);
+    expect(itemTop(2), 200.0);
+    expect(itemBottom(2), 300.0);
+
+    // Newly removed item 0's height should animate from 100 to 0 over 100ms
+
+    // Item's 0, 1, 2 at 0, 50, 150. Item 0's height is 50.
+    await tester.pump();
+    await tester.pump(const Duration(milliseconds: 50));
+    expect(itemTop(0), 0.0);
+    expect(itemBottom(0), 50.0);
+    expect(itemTop(1), 50.0);
+    expect(itemBottom(1), 150.0);
+    expect(itemTop(2), 150.0);
+    expect(itemBottom(2), 250.0);
+
+    // Item's 0, 1, 2 at 0, 0, 0. Item 0's height is 0.
+    await tester.pumpAndSettle();
+    expect(itemTop(0), 0.0);
+    expect(itemBottom(0), 0.0);
+    expect(itemTop(1), 0.0);
+    expect(itemBottom(1), 100.0);
+    expect(itemTop(2), 100.0);
+    expect(itemBottom(2), 200.0);
+   });
+}
