本篇文章主要来论述flutter中解决多个ListView嵌套的问题。

ShrinkWrap

当咱们运用ListView嵌套多个ListView的时分,咱们需要将嵌套的ListViewshrinkWrap属性值设置为trueshrinkWrap属性会强制评价整个内部列表,允许它恳求有限的高度,而不是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