Flutter中如何创建3:1宽度比的自适应高度双列卡片
解决Flutter卡片右侧列高度填充问题
你的问题核心是右侧红色背景容器没有填满Row的整个高度,导致上下出现空白。只需以下两处修改即可解决:
- 给外层的
Row添加crossAxisAlignment: CrossAxisAlignment.stretch,强制两个子组件拉伸至Row的最大高度; - 将右侧
Column的mainAxisAlignment改为MainAxisAlignment.spaceBetween,让内容自动分布在顶部和底部,红色背景会自然填满整个高度(如果希望内容全部靠上,也可以保留MainAxisAlignment.start,但要给Column加上mainAxisSize: MainAxisSize.max)。
修改后的完整代码:
Card( elevation: 2, clipBehavior: Clip.antiAlias, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), margin: const EdgeInsets.only(top: 10, bottom: 0, left: 10, right: 10), child: Row( // 新增:让子组件拉伸填满Row高度 crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Flexible( flex: 3, fit: FlexFit.tight, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 8.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TimelineTile( alignment: TimelineAlign.start, isFirst: true, afterLineStyle: const LineStyle(color: TruckerAppTheme.grey, thickness: 2), indicatorStyle: IndicatorStyle(color: Colors.white, padding: const EdgeInsets.all(0), iconStyle: IconStyle(fontSize: 28, iconData: Icons.location_on_rounded, color: TruckerAppTheme.grey)), endChild: Container( padding: const EdgeInsets.fromLTRB(8.0, 8, 0, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox( child: Text(widget.load.pickupCity != null ? "${widget.load.pickupCity}, ${widget.load.pickupState}" : "${widget.load.pickupState}", overflow: TextOverflow.visible, style: TruckerAppTheme.locationText)), SizedBox( child: Text(DateFormat('dd-MMM-yy').format(DateFormat('yyyy-MM-dd').parse(widget.load.pickupTimeStamp!)).toString(), overflow: TextOverflow.ellipsis, style: TruckerAppTheme.bodyNormalSmall)), ], ), ), ), TimelineTile( alignment: TimelineAlign.start, isLast: true, beforeLineStyle: const LineStyle(color: TruckerAppTheme.grey, thickness: 2), indicatorStyle: IndicatorStyle(color: Colors.white, padding: const EdgeInsets.all(0), iconStyle: IconStyle(fontSize: 28, iconData: Icons.flag_rounded, color: TruckerAppTheme.grey)), endChild: Container( padding: EdgeInsets.fromLTRB(8.0, 8, 0, (widget.load.dropTimeStamp != null) ? 0 : 7), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox( child: Text(widget.load.dropCity != null ? "${widget.load.dropCity}, ${widget.load.dropState}" : "${widget.load.dropState}", overflow: TextOverflow.visible, style: TruckerAppTheme.locationText)), (widget.load.dropTimeStamp != null) ? Text(DateFormat('dd-MMM-yy').format(DateFormat('yyyy-MM-dd').parse(widget.load.dropTimeStamp!)).toString(), overflow: TextOverflow.ellipsis, style: TruckerAppTheme.bodyNormalSmall) : Container(), ], ), ), ), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ widget.load.materialType == "" ? Flexible( child: Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Text( "${widget.load.loadWeight} ${widget.load.loadUnits.toString()[0] + widget.load.loadUnits.toString().substring(1).toLowerCase()} • ${VehicleTypeMapping().vehicleTypeMapping[widget.load.vehicleType!]!.value}", style: TruckerAppTheme.quantityText, ), )) : Flexible( child: Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Text( "${widget.load.loadWeight} ${widget.load.loadUnits.toString()[0] + widget.load.loadUnits.toString().substring(1).toLowerCase()} • ${widget.load.materialType} • ${VehicleTypeMapping().vehicleTypeMapping[widget.load.vehicleType!]!.value}", style: TruckerAppTheme.quantityText, ), )), ], ) ], ), ), ), Flexible( flex: 1, fit: FlexFit.tight, child: Container( padding: const EdgeInsets.only(bottom: 8, top: 8, right: 8, left: 8), margin: EdgeInsets.only(right: 0, top: 0, bottom: 0, left: 1), decoration: BoxDecoration(color: TruckerAppTheme.primaryColor.withOpacity(0.5), borderRadius: BorderRadius.circular(0)), child: Column( // 修改:让内容分布在上下,背景填满高度 mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Price", style: TruckerAppTheme.quantityText, ), widget.load.perTonneAmount == null ? Text( "Pending", style: TruckerAppTheme.pricePendingText, ) : Text( "₹ ${widget.load.perTonneAmount} Per Tonne", style: TruckerAppTheme.pricePendingText, ), ], ), Text( "Bid Now", style: TextStyle(fontSize: 14), ), ], ), ), ) ], ), )
另外,我把右侧的固定高度SizedBox(height:40)替换成了嵌套Column+MainAxisAlignment.spaceBetween的方式,这样布局会更自适应,不会出现固定高度导致的适配问题。
内容的提问来源于stack exchange,提问作者szervay
相关产品推荐
相关产品推荐

