diff --git a/animations/README.md b/animations/README.md index e2d9c10e9..fdc981017 100644 --- a/animations/README.md +++ b/animations/README.md @@ -12,7 +12,7 @@ Sample apps that showcasing Flutter's animation features Building blocks and patterns -1. **AnimatedContainerDemo** Demonstrates how to use `AnimatedContainer` +1. **AnimatedContainerDemo** Demonstrates how to use `AnimatedContainer` 2. **PageRouteBuilderDemo** Demonstrates how to use `Tween` and `Animation` to *build a custom page route transition. 3. **AnimationControllerDemo** Demonstrates how to use an `AnimationController`. @@ -23,6 +23,7 @@ Building blocks and patterns 6. **CustomTweenDemo** Demonstrates how to extend `Tween`. 7. **TweenSequenceDemo** Demonstrates how to use `TweenSequence` to build a button that changes between different colors. +8. **AnimatedList** Demonstrates how to use `AnimatedList` ### Misc diff --git a/animations/lib/main.dart b/animations/lib/main.dart index 188c1b1ff..be490bc34 100644 --- a/animations/lib/main.dart +++ b/animations/lib/main.dart @@ -11,6 +11,7 @@ import 'src/basics/04_tweens.dart'; import 'src/basics/05_animated_builder.dart'; import 'src/basics/06_custom_tween.dart'; import 'src/basics/07_tween_sequence.dart'; +import 'src/basics/08_animated_list.dart'; import 'src/misc/card_swipe.dart'; import 'src/misc/carousel.dart'; import 'src/misc/expand_card.dart'; @@ -57,6 +58,10 @@ final basicDemos = [ name: 'Tween Sequences', route: TweenSequenceDemo.routeName, builder: (context) => TweenSequenceDemo()), + Demo( + name: 'AnimatedList', + route: AnimatedListDemo.routeName, + builder: (context) => AnimatedListDemo()), ]; final miscDemos = [ diff --git a/animations/lib/src/basics/08_animated_list.dart b/animations/lib/src/basics/08_animated_list.dart new file mode 100644 index 000000000..ad3852961 --- /dev/null +++ b/animations/lib/src/basics/08_animated_list.dart @@ -0,0 +1,118 @@ +// Copyright 2020 The Flutter team. 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/material.dart'; +import 'package:flutter/widgets.dart'; + +class AnimatedListDemo extends StatefulWidget { + static String routeName = '/basics/08_animated_list'; + + _AnimatedListDemoState createState() => _AnimatedListDemoState(); +} + +class _AnimatedListDemoState extends State { + final GlobalKey _listKey = GlobalKey(); + final listData = initialListData; + + void addUser() { + setState(() { + int index = listData.length; + listData.add( + UserModel(firstName: "New", lastName: "Person"), + ); + _listKey.currentState + .insertItem(index, duration: Duration(milliseconds: 300)); + }); + } + + void deleteUser(int index) { + setState(() { + var user = listData.removeAt(index); + _listKey.currentState.removeItem( + index, + (context, animation) { + return FadeTransition( + opacity: + CurvedAnimation(parent: animation, curve: Interval(0.5, 1.0)), + child: SizeTransition( + sizeFactor: + CurvedAnimation(parent: animation, curve: Interval(0.0, 1.0)), + axisAlignment: 0.0, + child: _buildItem(user), + ), + ); + }, + duration: Duration(milliseconds: 600), + ); + }); + } + + Widget _buildItem(UserModel user, [int index]) { + return ListTile( + key: ValueKey(user), + title: Text(user.firstName), + subtitle: Text(user.lastName), + leading: CircleAvatar( + child: Icon(Icons.person), + ), + onLongPress: () => deleteUser(index), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + IconButton( + icon: Icon(Icons.add), + onPressed: addUser, + ), + ], + ), + body: SafeArea( + child: AnimatedList( + key: _listKey, + initialItemCount: initialListData.length, + itemBuilder: (context, index, animation) { + return FadeTransition( + opacity: animation, + child: _buildItem(listData[index], index), + ); + }, + ), + ), + ); + } +} + +class UserModel { + const UserModel({this.firstName, this.lastName}); + + final String firstName; + final String lastName; +} + +List initialListData = [ + UserModel( + firstName: "Govind", + lastName: "Dixit", + ), + UserModel( + firstName: "Greta", + lastName: "Stoll", + ), + UserModel( + firstName: "Monty", + lastName: "Carlo", + ), + UserModel( + firstName: "Petey", + lastName: "Cruiser", + ), + UserModel( + firstName: "Barry", + lastName: "Cade", + ), +];