解码Flutter(三)ListView嵌套
本篇文章主要来阐述flutter中解决多个ListView
嵌套的问题。
ShrinkWrap
当我们使用ListView
嵌套多个ListView
的时候,我们需要将嵌套的ListView
的shrinkWrap
属性值设置为true
。shrinkWrap
属性会强制评估整个内部列表,允许它请求有限的高度,而不是ListView
对象的通常高度,即无穷大。
通过下面代码示例,我们来探索ShrinkWrap
属性,
本着文章的可读性,本文只引用关键的示例代码
@override
void initState() {
super.initState();
for (int i = 0; i < numLists; i++) {
final _innerList = <ColorRow>[];
for (int j = 0; j < numberOfItemsPerList; j++) {
_innerList.add(const ColorRow());
}
innerLists.add(
ListView.builder(
itemCount: numberOfItemsPerList,
itemBuilder: (BuildContext context, int index) => _innerList[index],
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
),
);
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: numLists,
itemBuilder: (context, index) => innerLists[index]);
}
-
1,
shrinkWrap
会强制使ListView
一次性加载所有的内部子部件,以获取整个ListView
内容的整个高度。但这样会占用很大的内寸空间,当数量特别多的时候,会有严重的卡顿等性能问题。 -
2,
NeverScrollableScrollPhysics
: 使ListView
不可滑动。
嵌套List的懒加载 Slivers
我们可以使用 Slivers
让嵌套的ListView
里面的小部件进行懒加载。
1,将外层的ListView
变成SliverList
@override
Widget build(BuildContext context) {
return CustomScrollView(slivers: innerLists);
}
2,将 List<ListView>
变成List<SliverList>
List<SliverList> innerLists = [];
3,修改innerLists
的初始化方法
@override
void initState() {
super.initState();
for (int i = 0; i < numLists; i++) {
final _innerList = <ColorRow>[];
for (int j = 0; j < numberOfItemsPerList; j++) {
_innerList.add(const ColorRow());
}
innerLists.add(
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => _innerList[index],
childCount: numberOfItemsPerList,
),
),
);
}
}
这样改造就完成了,当我们运行时,并不会将ListView
中的所有Widget
一次性加载完成,当我们滑动的时候,会动态的去构建大部分Widget。
参考
转载自:https://juejin.cn/post/7094255437511393311