Flutter中为何无法定义嵌套Container的高度?
解决Flutter水平ListView中Item高度无法自定义的问题
我懂你的 frustration!当用水平滚动的ListView时,确实会遇到这种子组件高度被强制填满父容器的情况,我来给你拆解一下问题和解决方案:
问题根源
当ListView设置为scrollDirection: Axis.horizontal时,它的交叉轴(垂直方向)会给每个item施加一个"tight约束"——也就是item的高度必须等于ListView自身的高度(这里就是父Container的200)。所以你给item里的Container设置height:50会被这个约束直接覆盖,导致Card的高度跟着变成200。哪怕你用了Center包裹,也只是让内容在200高度的容器里居中,并没有改变容器本身的高度。
两种可行的解决方案
方案1:用UnconstrainedBox解除约束
UnconstrainedBox会移除父组件施加的约束,让子组件可以自由设置宽高:
final _recommendations = <String>["Embroidery", "Jewelry Making", "Tennis", "Hiking", "Disc Golf"]; return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Container( padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 16.0), height: 200, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: _recommendations.length, itemBuilder: (context, index) { // 用UnconstrainedBox包裹,解除高度约束 return UnconstrainedBox( child: Container( width: 150, height: 50, child: Card( color: Colors.blue, child: Center( child: Text(_recommendations[index]) ) ) ), ); } ) ) );
方案2:用Align让Item居中显示
如果你希望保持ListView的高度,同时让Card在垂直方向居中,用Align也是个不错的选择:
final _recommendations = <String>["Embroidery", "Jewelry Making", "Tennis", "Hiking", "Disc Golf"]; return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Container( padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 16.0), height: 200, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: _recommendations.length, itemBuilder: (context, index) { // Align会让子组件在可用空间内居中,不强制填满高度 return Align( alignment: Alignment.center, child: Container( width: 150, height: 50, child: Card( color: Colors.blue, child: Center( child: Text(_recommendations[index]) ) ) ), ); } ) ) );
额外小提示
如果你的Card不需要外层Container,也可以直接给Card设置尺寸,代码会更简洁:
return Align( alignment: Alignment.center, child: Card( color: Colors.blue, elevation: 4, child: SizedBox( width: 150, height: 50, child: Center(child: Text(_recommendations[index])), ), ), );
内容的提问来源于stack exchange,提问作者Dallin Davis
相关产品推荐
相关产品推荐

