本篇文章主要来论述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。
参考
Nested lists – ShrinkWrap vs Slivers dart pad
ShrikWrap 对比 Slivers