Flutter模态底部弹窗报错:Vertical viewport was given unbounded height
解决Flutter模态底部弹窗内嵌ListView的"Vertical viewport was given unbounded height"错误
这个错误的核心原因是:Column是垂直方向无约束的容器,而ListView默认会试图占据无限的垂直高度,两者组合触发了布局冲突。
你可以通过以下两种方式解决,推荐第二种(更适配底部弹窗的场景):
方法1:给ListView添加shrinkWrap: true
让ListView根据子项的总高度自动收缩自身尺寸,不再试图抢占无限空间:
ListView.builder( shrinkWrap: true, // 添加这一行 physics: const ScrollPhysics(), itemCount: widget.user.myEvents!.length, // ... 其余代码不变 )
方法2:用Expanded包裹ListView
让ListView占据Column中除顶部标题外的剩余可用空间,保证列表在弹窗范围内滚动,这是底部弹窗场景下更稳定的方案:
_showModal(BuildContext context) { showModalBottomSheet( context: context, builder: (context) => Container( margin: const EdgeInsets.only(top: 10), child: Column(children: [ Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Select event', style: Theme.of(context).textTheme.headlineMedium) ]), // 用Expanded包裹ListView Expanded( child: ListView.builder( physics: const ScrollPhysics(), itemCount: widget.user.myEvents!.length, itemBuilder: (contex, index) { return StreamBuilder( stream: di .gt<GetSingleEventUseCase>() .call(widget.user.myEvents![index]), builder: (context, snapshot) { if (snapshot.hasData) { return TileSettings( title: snapshot.data!.first.eventName!, leading: snapshot.data!.first.guestsid! .contains(widget.otherUser.uid) || snapshot.data!.first.guestsid! .contains(widget.otherUser.uid) ? const Image(image: ticketLinear) : const Image(image: ticket), onTap: () {}, trailing: const SizedBox.shrink()); } else { return TileSettings( title: 'No events', leading: const Image(image: cross), onTap: () {}, trailing: const SizedBox.shrink()); } }); }), ) ]))); }
两种方案的区别:
shrinkWrap: true适合列表项较少的场景,ListView会完全包裹所有子项;如果列表很长,可能会因一次性渲染所有子项导致性能问题。Expanded会约束ListView在弹窗的可用高度内,列表超出部分可滚动,适配绝大多数底部弹窗的使用场景。
内容的提问来源于stack exchange,提问作者Mus
相关产品推荐
相关产品推荐

