List的动画版。
AnimatedList中两个关键的属性就是itemBuilder、initialItemCount:itemBuilder是构建AnimatedList的方法;initialItemCount是初始构件项目数量。 现在开始使用AnimatedList:
import 'package:flutter/material.dart; import 'dart:math'; class AnimatedListRoute extends StatefulWidget{ _AnimatedListRouteState createState() => _AnimatedListRouteState(); } class _AnimatedListRouteState extends State<AnimatedListRoute>{ final _listKey = GlobalKey<AnimatedListState>(); List<int> _data; Tween<Offset> _tween = Tween<Offset>(begin: Offset(1,0), end: Offset(0,0)); @override void initState() { // TODO: implement initState super.initState(); _data = [12,34,43,12,54]; } Widget myListItem(String text, Animation animation) { return SlideTransition( position: animation.drive(CurveTween(curve: Curves.bounceOut)).drive(_tween), child: Container( margin: EdgeInsets.symmetric(vertical: 10.0), constraints: BoxConstraints.tight(Size(double.infinity, 70)), alignment: Alignment.center, child: Text('$text', style: TextStyle(color: Colors.white),), color: Colors.primaries[int.parse(text) % Colors.primaries.length], ) ); } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text('AnimatedListState'), ), body: Stack( children: <Widget>[ Padding( padding: EdgeInsets.symmetric(horizontal: 20.0), child: AnimatedList( key: _listKey, itemBuilder: (context, index, animation) => myListItem(_data[index].toString(), animation), initialItemCount: _data.length, ), ), Positioned( bottom: 30, right: 10, child: FloatingActionButton( heroTag: 'remove', onPressed: () { }, child: Icon(Icons.remove), ), ), Positioned( bottom: 30, right: 70, child: FloatingActionButton( heroTag: 'add', onPressed: () { }, child: Icon(Icons.add), ), ) ], ) ); } }效果 现在点击下方的添加、删除按钮是没有任何响应的,接下来我们为添加按钮添加事件,当点击添加按钮在列表尾部添加一个项目,点击删除则删除列表最后一个项目。AnimatedListState为我们提供了添加及删除项目的方法:insertItem、removeItem,通过这两个方法完成我们的需求。要想获取AnimatedListState可通过我们定义的_listKey或者使用AnimatedList.of(context),两者区别在于AnimatedList.of(context)只能在项目内部使用(此处context为itemBuilder的context),而_listKey在外部也可以获取到AnimatedListState。注意在操作Item的同时要更新我们的数据。
Positioned( bottom: 30, right: 10, child: FloatingActionButton( heroTag: 'remove', onPressed: () { int data = _data.last; int index = _data.length - 1; _data.remove(data); _listKey.currentState.removeItem(index, (context, animation) => myListItem(context, data.toString(), animation), duration: Duration(seconds: 1)); }, child: Icon(Icons.remove), ), ), Positioned( bottom: 30, right: 70, child: FloatingActionButton( heroTag: 'add', onPressed: () { int num = Random().nextInt(1000); _data.add(num); int index = _data.lastIndexOf(num); _listKey.currentState.insertItem(index, duration: Duration(seconds: 1)); }, child: Icon(Icons.add), ), )下面代码是AnimatedList.of(context)的示例,将下面代码替换SlideTransition中的Container的child即可:
Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Text('$text', style: TextStyle(color: Colors.white),), IconButton( icon: Icon(Icons.delete_forever, color: Colors.white,), onPressed: (){ int index = _data.indexOf(int.parse(text)); _data.removeAt(index); AnimatedList.of(context).removeItem(index, (context, animation) => myListItem(context, text, animation), duration: Duration(seconds: 1)); }, ) ], ),重新运行项目:
