AnimatedList
是一個有狀態的 Widget,對應的 State 類型為AnimatedListState
AnimatedList 的結構如下:
const AnimatedList({
Key? key,
required Widget Function(BuildContext, int, Animation<double>) itemBuilder,//數據構造器
int initialItemCount = 0,//初始化的數據的總長度
Axis scrollDirection = Axis.vertical,//滾動方向
bool reverse = false,//是否從下往上顯示
ScrollController? controller,//滾動的controller,非必填,控制列表的滾動位置
bool? primary,//是否關聯父級滾動
ScrollPhysics? physics,//如何響應用戶操作
bool shrinkWrap = false,
EdgeInsetsGeometry? padding,//內邊距
Clip clipBehavior = Clip.hardEdge,
})
State 裡有兩個方法可以添加和刪除列表裡的元素:
注意,如果 List 綁定了數據源 List 的話,不能直接通過 remove 或者 add 元素達到更新列表的效果,還需要執行下面的方法:
//插入元素
void insertItem(
int index,
{Duration duration = _kDuration}
)
//刪除元素
void removeItem(
int index,
Widget Function(BuildContext, Animation<double>) builder, {
Duration duration = _kDuration,
})
添加和刪除的時候都會顯示指定的動畫
使用 insertItem、removeItem 時通常需要配合 globalKey,但 globalKey 需要指定泛型,這樣才能調用到增加和刪除列表元素的方法:
final globalKey = GlobalKey<AnimatedListState>();
添加元素的時候只需要:
list.add("新增數據");
globalKey.currentState!.insertItem(list.length - 1);
刪除元素的時候比較麻煩,因為需要顯示元素離開時候的動畫然後再刪除對應數據源的條目:
一般我們需要建一個
_buildItem
方法來動態創建子元素,執行removeItem
的時候先在回調裡面創建一個一模一樣的子元素,如何使用動畫淡出,最後刪除數據數組中的數據即可.
//刪除元素
_delItem(index) {
globalKey.currentState!.removeItem(index, (context, animation) {
//獲取要刪除的元素,讓他淡出顯示
var removeItem = _buildItem(index);
return FadeTransition(
//執行動畫
opacity: animation,
child: removeItem,
);
});
list.removeAt(index); //刪除數組中的數據
}
完整代碼#
//AnimatedList
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//定義一個globalKey
final globalKey = GlobalKey<AnimatedListState>();
List<String> list = ["第一條數據", "第二條數據"];
bool flag = true;
Widget _buildItem(index) {
return ListTile(
title: Text(list[index]),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
//執行刪除
_delItem(index);
},
),
);
}
//刪除元素
_delItem(index) {
globalKey.currentState!.removeItem(index, (context, animation) {
//獲取要刪除的元素,讓他淡出顯示
var removeItem = _buildItem(index);
list.removeAt(index); //刪除數組中的數據
return FadeTransition(
//執行動畫
opacity: animation,
child: removeItem,
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("kano")),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
//這樣直接操作list不會對AnimatedList生效
onPressed: () {
// setState(() {
// list.add("新增數據");
// });
///使用AnimatedList中的insertItem方法
list.add("新增數據");
globalKey.currentState!.insertItem(list.length - 1);
},
),
//帶有動畫的List列表
body: AnimatedList(
key: globalKey,
initialItemCount: list.length,
itemBuilder: (context, index, animation) {
//fade過渡 opacity 進入從0到1 離開則相反
return FadeTransition(opacity: animation);
//scale過渡
// return ScaleTransition(scale: animation);
},
),
);
}
}