Flutter实现Scaffold整个body可滚动时出现异常如何解决?
问题根因
报错本质是无限高度约束和Expanded的逻辑冲突:
- SingleChildScrollView在垂直方向没有上限高度,内部的Column会默认适配子组件的总高度,不会给子组件提供有限的高度边界
- 代码中使用的Expanded作用是填充父组件提供的剩余有限空间,父组件高度无界的情况下找不到“剩余空间”,就会抛出布局异常
具体修复方案
按照以下规则修改代码即可解决:
- 删掉所有Expanded组件,全页面滚动场景下不需要让某一部分占剩余空间,所有组件直接展示自身高度即可
- 保留ListView.builder的
shrinkWrap: true和physics: NeverScrollableScrollPhysics()配置,让它跟随外层SingleChildScrollView一起滚动,不需要自身的滚动能力 - 给嵌套的Column都加上
mainAxisSize: MainAxisSize.min,让它适配子组件总高度,不撑满父容器
修复后的body代码参考
body: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, // 新增:适配子组件总高度 crossAxisAlignment: CrossAxisAlignment.start, children: [ StreamBuilder<QuerySnapshot>( stream:_someStreamingFunction(), builder: (context, snapshot) { if (snapshot.hasData) { // 移除了外层的Expanded return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, // 新增:适配子组件高度 children: [ Card( child: Container( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [] ), ), ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( 'Loading', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 18.0, ), ), SpinKitThreeBounce( color: Colors.black, size: 12.0, ), ], ), // 移除了外层的Expanded,保留原有ListView配置 ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: transactions.length != 0 ? transactions.length : 0, itemBuilder: (context, index) { return CustomTile(.....); }, ) ], ); } // 补全无数据时的返回占位,避免空返回异常 return const Padding( padding: EdgeInsets.all(20), child: Center(child: CircularProgressIndicator()), ); } ), ], ), ),
注意事项
- 必须给StreamBuilder补全所有状态的返回值,除了
snapshot.hasData之外,还要处理加载中、报错的场景,否则可能抛出空返回的布局异常 - 如果页面有需要固定在顶部/底部的组件,不要放在SingleChildScrollView内部,放在外部和SingleChildScrollView平级即可
内容的提问来源于stack exchange,提问作者Arud
相关产品推荐
相关产品推荐

