flutter列表视图代码片
Easul Lv4

动态创建列表视图

折叠代码块DART 复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int _tvIndex = 0;
List tvLinks = ["CCTV-1", "CCTV-2"];

// 如果想要在滚动的时候监听滚动到哪里了,可以给ListView添加ScrollController
// 这时ListView需要放到Scrollbar下
Column(children: [
ListTile(
textColor: Colors.black,
tileColor: Colors.grey[200],
title: Text("列表头"),
),
Divider(height: .0),
ListView.separated(
itemCount: tvLinks.length,
// 因为并不是一下子将所有的数据加载出来,所以当滑动的时候index会变化,
// 所以可以判断一下index是不是刷新到了最后一个,然后就可以触发动态加载
// 因为这个是在滑动的过程中执行的,所以直接在build中进行更新即可
itemBuilder: (context, index) {
return InkWell(
// 如果每个列表项点击后需要对该列表项进行操作,可以创建一个全局变量,保存index
// onTap点击时可以setState更新该变量的值,并通知组件更新状态
onTap: () {
setState(() {
_tvIndex = index;
});
},
child: ListTile(
// 判断组件为是自己的组件时,进行特殊操作
title: _tvIndex == index
? Text("使用了源${index + 1}")
: Text("源${index + 1}"),
),
));
},
// 设置分割线的样式
separatorBuilder: (BuildContext context, int index) {
return const Divider(height: .0);
},
)
]);

动画列表添加删除条目

折叠代码块DART 复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
class _AnimatedListRouteTestState extends State<AnimatedListTestRoute> {
var data = <String>[];
int counter = 5;

final globalKey = GlobalKey<AnimatedListState>();

@override
void initState() {
for (var i = 0; i < counter; i++) {
data.add('${i + 1}');
}
super.initState();
}

@override
Widget build(BuildContext context) {
return Stack(
children: [
AnimatedList(
key: globalKey,
initialItemCount: data.length,
itemBuilder: (
BuildContext context,
int index,
Animation<double> animation,
) {
//添加列表项时会执行渐显动画
return FadeTransition(
opacity: animation,
child: buildItem(context, index),
);
},
),
buildAddBtn(),
],
);
}

// 创建一个 “+” 按钮,点击后会向列表中插入一项
Widget buildAddBtn() {
return Positioned(
bottom: 30,
left: 0,
right: 0,
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
// 添加一个列表项
data.add('${++counter}');
// 告诉列表项有新添加的列表项
globalKey.currentState!.insertItem(data.length - 1);
print('添加 $counter');
},
),
);
}

// 构建列表项
Widget buildItem(context, index) {
String char = data[index];
return ListTile(
//数字不会重复,所以作为Key
key: ValueKey(char),
title: Text(char),
trailing: IconButton(
icon: Icon(Icons.delete),
// 点击时删除
onPressed: () => onDelete(context, index),
),
);
}

void onDelete(context, index) {
setState(() {
globalKey.currentState!.removeItem(
index,
(context, animation) {
// 删除过程执行的是反向动画,animation.value 会从1变为0
var item = buildItem(context, index);
print('删除 ${data[index]}');
data.removeAt(index);
// 删除动画是一个合成动画:渐隐 + 缩小列表项告诉
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
//让透明度变化的更快一些
curve: const Interval(0.5, 1.0),
),
// 不断缩小列表项的高度
child: SizeTransition(
sizeFactor: animation,
axisAlignment: 0.0,
child: item,
),
);
},
duration: Duration(milliseconds: 200), // 动画时间为 200 ms
);
});
}
}
 评论
来发评论吧~
Powered By Valine
v1.5.2