问题描述
我有一个AnimatedList
,我可以添加和删除项目。我的问题是,当我将一个项目添加到列表的顶部时,其下方的项目会向下跳转以为其留出空间,而不是平稳过渡。
我发现this answer提供了一种解决方案,可以在移除项目时使它们顺利动画,但是我无法获得相同的解决方案来插入项目。
这是我到目前为止所拥有的。当该项目被添加到列表的顶部时,其下方的元素会平滑移动。但是,新元素的按比例放大过渡也随之发生。
class Foo extends StatefulWidget {
Foo({Key key}) : super(key: key);
final kDuration = const Duration(seconds: 1);
@override
_FooState createState() => _FooState();
}
class _FooState extends State<Foo> {
final _key = GlobalKey<AnimatedListState>();
List<Color> _items;
int _counter;
@override
void initState() {
super.initState();
_items = <Color>[];
_counter = 0;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Animated List Spike'),),body: AnimatedList(
key: _key,initialItemCount: _items.length,itemBuilder: (context,index,animation) {
return Stack(
children: [
// This transition creates the smooth shift-down effect.
SizeTransition(
sizefactor: animation.drive(Tween(begin: 0,end: 1)),child: Padding(
padding: const EdgeInsets.all(8.0),child: Container(
height: 64,color: Colors.transparent,// This is the content we actually want to show.
Align(
alignment: Alignment.topCenter,heightFactor: 0,child: SlideTransition(
position: Tween(
begin: Offset(0,-0.5),end: Offset(0,0),).animate(animation),child: ScaleTransition(
scale: CurveTween(curve: Curves.eaSEOutBack)
.animate(animation),child: Padding(
padding: const EdgeInsets.all(8.0),child: Card(
color: _items[index],child: Container(height: 64),],);
},floatingActionButton: FloatingActionButton(
onpressed: addItem,child: const Icon(Icons.add),);
}
void addItem() {
_items.insert(0,Colors.primaries[_counter++ % Colors.primaries.length]);
_key.currentState.insertItem(0,duration: widget.kDuration);
}
}
有没有一种方法可以使元素平滑移动,然后然后引入新的元素比例?
解决方法
解决方案是使用Interval
曲线。通过使一条曲线的末端在0.5
标记处,另一条曲线从此开始,我能够使元素向下滑动,然后将新的元素比例放大。
CurveTween(
curve: Interval(
0.5,// Start halfway through the animation.
1.0,// Stop at the end of the animation.
curve: Curves.easeOutBack,),).animate(animation),
完整的问题解决方案:
itemBuilder: (context,index,animation) {
return Stack(
children: [
SizeTransition(
sizeFactor: animation.drive(
CurveTween(
curve: Interval(
0.0,0.5,curve: Curves.linear,child: Padding(
padding: const EdgeInsets.all(8.0),child: Container(
height: 64,color: Colors.transparent,Align(
alignment: Alignment.topCenter,heightFactor: 0,child: ScaleTransition(
scale: CurveTween(
curve: Interval(
0.5,1.0,curve: Curves.easeOutBack,child: Padding(
padding: const EdgeInsets.all(8.0),child: Card(
color: _items[index],child: Container(height: 64),],);