Commit acf102be authored by Hans Muller's avatar Hans Muller Committed by GitHub

AnimatedList (#9649)

parent 67169043
This diff is collapsed.
......@@ -10,6 +10,7 @@ library widgets;
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';
......
// 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);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment