AnimatedList
可以在列表中插入或删除节点时执行一个动画,在需要添加或删除列表项的场景中会提高用户体验。先看一下AnimatedList
的构造:
const AnimatedList({
super.key,
required this.itemBuilder,//滚动到视图中时在列表中构建项目
this.initialItemCount = 0,//ch
this.scrollDirection = Axis.vertical,
this.reverse = false,
this.controller,
this.primary,
this.physics,
this.shrinkWrap = false,
this.padding,
this.clipBehavior = Clip.hardEdge,
})
AnimatedList
是一个 StatefulWidget
,它对应的 State
类型为 AnimatedListState
,添加和删除元素的方法位于 AnimatedListState
中:
void insertItem(int index, { Duration duration = _kDuration });
void removeItem(int index, AnimatedListRemovedItemBuilder builder, { Duration duration = _kDuration }) ;
获取AnimatedListState的两种方法:
- 通过设置key: 例子:
import 'package:flutter/material.dart';
class AnimatedListPage extends StatefulWidget {
const AnimatedListPage({Key? key}) : super(key: key);
@override
State<AnimatedListPage> createState() => _AnimatedListPageState();
}
class _AnimatedListPageState extends State<AnimatedListPage> {
final _items = [];
final _key = GlobalKey<AnimatedListState>();
//添加
void _addItem() {
_items.insert(0, 'Item ${_items.length + 1}');
_key.currentState!.insertItem(0,duration: const Duration(seconds: 1));
}
//删除
void _removeItem(int index){
_key.currentState!.removeItem(index, (context, animation) {
return SizeTransition(
sizeFactor: animation,
child: const Card(
margin: EdgeInsets.all(10),
elevation: 10,
color: Colors.purple,
child: ListTile(
contentPadding: EdgeInsets.all(15),
title: Text('删除'),
),
)
);
},duration: const Duration(seconds: 1));
_items.removeAt(index);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('使用key的方法'),),
body: AnimatedList(
key: _key,
initialItemCount: 0,
padding: const EdgeInsets.all(10),
itemBuilder: (context,index,animation){
return SizeTransition(
sizeFactor: animation,
child: Card(
margin: const EdgeInsets.all(10),
elevation: 10,
color: Colors.orange,
child: ListTile(
contentPadding: const EdgeInsets.all(15),
title: Text(_items[index]),
trailing: IconButton(
icon:const Icon(Icons.delete),
onPressed: ()=>_removeItem(index),
),
),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _addItem,child: const Icon(Icons.add),
),
);
}
}
- 通过
AnimatedList.of(context)
方法 例子:
import 'package:flutter/material.dart';
class AnimatedListPage extends StatefulWidget {
const AnimatedListPage({Key? key}) : super(key: key);
@override
State<AnimatedListPage> createState() => _AnimatedListPageState();
}
class _AnimatedListPageState extends State<AnimatedListPage> {
final _items = ["Item 0"];
final _key = GlobalKey<AnimatedListState>();
//添加
void _addItem() {
_items.insert(0, 'Item ${_items.length + 1}');
_key.currentState!.insertItem(0,duration: const Duration(seconds: 1));
}
//删除
void _removeItem(int index,BuildContext context) {
AnimatedList.of(context).removeItem(index, (context, animation) {
return FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
child: SizedBox(
height: 150,
child: Card(
margin: const EdgeInsets.symmetric(vertical: 20),
elevation: 10,
color: Colors.red[400],
child: const Center(
child: Text('list',style: TextStyle(fontSize: 28),),
),
),
),
),
);
} ,duration: const Duration(seconds: 1));
_items.removeAt(index);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AnimatedList.of'),
actions: [
IconButton(
onPressed: _addItem,
icon: const Icon(Icons.plus_one_outlined),
)
],
),
body: AnimatedList(
key: _key,
initialItemCount: 1,
padding: const EdgeInsets.all(10),
itemBuilder: (context,index, animation){
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-1, -0.5),
end:const Offset(0, 0),
).animate(animation),
child: RotationTransition(
turns: animation,
child: SizeTransition(
axis: Axis.vertical,
sizeFactor: animation,
child: SizedBox(
height: 150,
child: InkWell(
onTap: ()=>_removeItem(index, context),
child: Card(
margin: const EdgeInsets.symmetric(vertical: 20),
elevation: 10,
color: Colors.primaries[(index*100)% Colors.primaries.length][300],
child: Center(
child: Text(_items[index],style: const TextStyle(fontSize: 28),),
),
),
),
),
),
),
);
},
),
);
}
}