如何在Flutter中创建宽度比为3:1的2列卡片

jhdbpxl9  于 2023-03-19  发布在  Flutter
关注(0)|答案(3)|浏览(152)

我正在尝试创建一张卡片,它可以有2列,宽度比为3:1。问题是,这张卡片必须根据它的内容有动态高度。类似这样:card that i'm trying to create这是我现在拥有的:what I have right now红色列顶部和底部白色也需要为红色。
这是我的代码:

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(
        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(
                              // width: MediaQuery.of(context).size.width * 0.65,
                              child: Text(widget.load.pickupCity != null ? "${widget.load.pickupCity}, ${widget.load.pickupState}" : "${widget.load.pickupState}",
                                  overflow: TextOverflow.visible, style: TruckerAppTheme.locationText)),
                          SizedBox(
                              // width: MediaQuery.of(context).size.width * 0.6,
                              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(
                              //  width: MediaQuery.of(context).size.width * 0.6,
                              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,
                              ),
                            )),
                      // const Icon(Icons.arrow_forward, color: Colors.grey)
                    ],
                  )
                ],
              ),
            ),
          ),
          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.start,
                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,
                        ),
                  const SizedBox(
                    height: 40,
                  ),
                  Text(
                    "Bid Now",
                    style: TextStyle(fontSize: 14),
                  ),
                ],
              ),
            ),
          )
        ],
      ),
    )

我尝试过使用固有高度、扩展等,但没有效果。

8ehkhllq

8ehkhllq1#

方法1.尝试调整小部件的大小

testWidget(BuildContext context) {
        return 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(
            children: [
              Expanded(
                  child: Container(
                color: Colors.amber,
              )),
              SizedBox(
                width: MediaQuery.of(context).size.width / 3,
                height: 100,
                child: Flexible(
                    child: Container(
                  color: Colors.blue,
                )),
              )
            ],
          ),
        );
      }
polhcujo

polhcujo2#

我试过了,效果和预期的一样。确保Container的边距为零。

Card(
              elevation: 2,
              child: Row(
                children: [
                  Flexible(
                    flex: 3,
                    fit: FlexFit.tight,
                    child: Container(
                      color: Colors.black,
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: const [
                          Padding(
                            padding: EdgeInsets.all(4),
                            child: Text('ITEM!'),
                          ),],
                      ),
                    ),
                  ),
                  Flexible(
                    flex: 1,
                    fit: FlexFit.tight,
                    child: Container(
                      color: Colors.red.withOpacity(0.7),
                      padding: const EdgeInsets.all(8),
                      child: Column(
                        mainAxisSize: MainAxisSize.max,
                        children: const [
                          Padding(
                            padding: EdgeInsets.all(4),
                            child: Text('ITEM!'),
                          ),
                     ...
                        ],
                      ),
                    ),
                  )
                ],
              ))
70gysomp

70gysomp3#

您可以使用自定义裁剪器来实现这一点,如下所示

Widget build(BuildContext context) {
return Stack(
  children: [
    Container(
      width: MediaQuery.of(context).size.width - 40,
      margin: const EdgeInsets.only(right: 5),
      decoration: BoxDecoration(
        color: Colors.red,
        borderRadius: BorderRadius.circular(10),
      ),
    ),
    ClipPath(
      clipper: PromoCustomClipper(),
      child: Container(
        width: MediaQuery.of(context).size.width - 40,
        margin: const EdgeInsets.only(right: 5),
        decoration: BoxDecoration(
          color: Colors.grey,
          borderRadius: BorderRadius.circular(10),
        ),
        child: Padding(
          padding: const EdgeInsets.only(top: 10, left: 15, right: 125),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Content dynamic height'),
              const SizedBox(height: 15),
              Text('Content description')
            ],
          ),
        ),
      ),
    ),
  ],
);

}
//自定义裁剪器类

class PromoCustomClipper extends CustomClipper<Path>{
@override
  getClip(Size size) {
  var path = Path();
  path.lineTo(0, 0);
  path.lineTo(0, size.height);
  path.lineTo(230, size.height);
  path.lineTo(230, 0);
  return path;

}
@覆盖
布尔值shouldReclip(协变自定义裁剪器旧裁剪器){
返回false;
}
}

相关问题