Flutter中ListView.builder嵌套Column出现性能下降及布局问题
问题原理说明
初始代码卡顿的根源
当可滚动容器(SingleChildScrollView)嵌套ListView.builder/GridView.builder时,子列表会失去懒加载特性:父级滚动容器不会给子列表提供固定的视口高度约束,子列表会一次性构建所有item,商品数量较多时就会出现严重性能损耗,滚动卡顿。
调整后无法添加底部组件的原因
你去掉外层嵌套的滚动容器后,直接用单个ListView.builder作为滚动主体,恢复了懒加载特性,性能问题得到解决,但此时你设置的itemCount: productListObj.length仅覆盖了商品列表的长度,没有预留额外位置渲染底部其他组件。
解决方案
对你现有代码改动最小的方案是调整ListView.builder的配置,预留额外的item位置给底部组件即可,示例代码如下:
Scaffold( body: RefreshIndicator( onRefresh: () { return refreshUI(setState); }, child: ListView.builder( controller: scrollController, // 总item数 = 商品数量 + 1(底部组件占位) itemCount: productListObj.length + 1, itemBuilder: (BuildContext context, int index) { // 索引小于商品数量时渲染商品卡片 if (index < productListObj.length) { return InkWell( onTap: (){ showDialog(context: context, builder: (BuildContext context){ return DetailsProducts(context,productListObj[index]); }); }, child: cards(index, price) ); } // 最后一个索引位置渲染你需要的其他组件 else { return Column( children: [ // 此处放置你需要的底部组件,比如说明文案、推荐模块、加载更多提示等 ], ); } } ), ) )
如果底部有多个独立模块需要区分,可将itemCount设置为商品数量 + 底部模块数量,在itemBuilder中按index区间分别返回对应组件即可,全程保持懒加载特性,不会出现性能问题。
如果页面结构更复杂,也可以使用CustomScrollView搭配多个Sliver组件实现,比如用SliverList渲染商品列表,SliverToBoxAdapter渲染其他固定模块,效果一致。
内容的提问来源于stack exchange,提问作者Marcos Gianetti
相关产品推荐
相关产品推荐

