Flutter 如何让ListView中的容器填充剩余空间且溢出时可滚动
实现方案
该需求可以实现,推荐使用CustomScrollView搭配SliverFillRemaining组件完成,完全满足你提出的两项要求。
推荐实现代码
return Scaffold( body: SafeArea( child: Container( color: Colors.blueAccent, child: CustomScrollView( slivers: [ // 黄色固定高度容器 SliverToBoxAdapter( child: Container( color: Colors.yellow, height: 100 ), ), // 10dp间距 const SliverToBoxAdapter( child: SizedBox(height: 10), ), // 自动填充剩余高度的黑色容器 SliverFillRemaining( hasScrollBody: false, child: Container( color: Colors.black, // 此处放置黑色容器的内部内容 child: /* 你的内部业务组件 */, ), ) ], ), ), ), );
方案说明
- 为什么不直接用原生ListView:原生ListView的子元素高度默认由自身内容决定,没有自动计算父容器剩余可用高度的能力,无法实现内容较少时撑满剩余空间的需求
SliverFillRemaining核心特性完全匹配需求:- 当内部内容高度小于CustomScrollView的剩余可用高度时,组件高度自动匹配剩余高度,实现黑色容器填充效果
- 当内部内容高度大于CustomScrollView的剩余可用高度时,组件高度自动匹配内容高度,整个CustomScrollView变为可滚动状态,不会出现内容溢出报错
- 参数说明:
hasScrollBody: false表示该Sliver的高度由内部内容决定,不需要自身支持滚动,滚动能力交给外层CustomScrollView即可,符合你要求整个列表滚动的需求。
可选方案(基于原生ListView实现)
如果不想替换ListView结构,也可以通过LayoutBuilder预计算剩余高度实现:
return Scaffold( body: SafeArea( child: LayoutBuilder( builder: (context, constraints) { // 获取父容器总高度 final totalHeight = constraints.maxHeight; // 扣除黄色容器高度+10间距,得到剩余可用高度 final remainHeight = totalHeight - 100 - 10; return Container( color: Colors.blueAccent, child: ListView( children: [ Container( color: Colors.yellow, height: 100 ), const SizedBox(height: 10), Container( // 给黑色容器设置最小高度约束 constraints: BoxConstraints( minHeight: remainHeight, ), color: Colors.black, child: /* 内部业务组件 */, ) ], ), ); } ), ), );
该方案的缺点是如果顶部黄色容器的高度是动态值,需要手动调整计算逻辑,灵活性低于Sliver方案。
内容的提问来源于stack exchange,提问作者Vingtoft
相关产品推荐
相关产品推荐

