【问题标题】:How to make a container take up the height of the parent widget?如何让容器占据父小部件的高度?
【发布时间】:2021-08-30 13:32:34
【问题描述】:

我的卡片布局如下所示:

它的代码如下:

Card(
        color: tap ? Colors.green : Colors.white,
        margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 3.0),
        child: Container(
          child: Row(
            children: [
              **Container(
                height: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
                width: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.only(topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
                  image: DecorationImage(
                      image: NetworkImage(widget.menuItem.image),
                      fit: BoxFit.cover
                  ),
                ),**
              ),
              SizedBox(
                width: 8.0,
              ),
              Expanded(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.baseline,
                      textBaseline: TextBaseline.alphabetic,
                      children: [
                        Text(
                          howManyThere() > 0 ? "${howManyThere()} x " : '',
                          style: addBTNHighlight,
                        ),
                        Expanded(
                          child: Text(
                            widget.menuItem.item_name,
                            overflow: TextOverflow.ellipsis,
                            style: tap ? TitleWhite18Bold : Title18bold,
                          ),
                        ),
                      ],
                    ),
                    Container(
                      child: Text(
                        widget.menuItem.description,
                        //overflow: TextOverflow.ellipsis,
                        style: tap ? SubTitleWhite13 : SubTitle13,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 4.0),
                      child: Text(
                        "£" + num.parse(widget.menuItem.price).toStringAsFixed(2),
                        style: tap ? priceHighlightSelected : priceHighlight,
                      ),
                    ),
                  ],
                ),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                      padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 6.0),
                      decoration: BoxDecoration(),
                      child: Text("ADD", style: tap ? priceHighlightWhite : addBTNHighlight)),
                ],
              ),
            ],
          ),
        ),
      )

如您所见,我几乎已经完成了我想要的布局,但有一个小问题可以在第一个和最后一个项目中看到。由于图像容器的给定宽度和高度,它会在顶部和底部留下一个间隙。

我希望宽度保持不变,但高度灵活并根据卡片本身的高度进行调整。有可能吗?

当我删除带有图像的容器的高度属性时,我得到了图像的空白

更新:我也尝试了 LayoutBuilder,但没有任何运气,它会抛出“不正确使用 ParentWidget”异常。我使用的代码如下:

Row(
            children: [
              widget.menuItem.image.endsWith('/')
                  ? Container()
                  : **LayoutBuilder(
                builder: (context, constraints){
                  return Container(
                    width: 70.0,
                    height: constraints.minHeight,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(5.0)),
                      image: DecorationImage(
                          image: NetworkImage(widget.menuItem.image),
                          fit: BoxFit.cover
                      ),
                    ),
                  );
                }**
              ),

【问题讨论】:

  • 您的代码不可重现。您可以尝试删除 height:70 并将您的 Row 包装在 IntrinsicHeight 小部件中。
  • 使用 BoxFit.fitHeight 或填充

标签: flutter flutter-layout flutter-web


【解决方案1】:

为了用卡片高度填充图像,您可以为容器提供所需的高度并将AspectRatio 小部件与ratio 1 包装在一起。这将始终有助于图像小部件填充父卡片高度。看看下面的代码。

父小部件

Container(
  margin: EdgeInsets.only(bottom: 12),
  height: 100,
  child: Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      AspectRatio(
        aspectRatio: 1,
          child: _pictureWidget(widget.menuItem.image),
        ),
       /// Replace `Container` with the needed widget
       Expanded(child: Container()),
     ],
   ),
 )

_pictureWidget

Widget _picture(String url) {
    return _pictureWidget(
      borderRadius: BorderRadius.only(
          topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
      child: Image.network(
        url != null ? url : "",
        fit: BoxFit.cover,
        loadingBuilder: (BuildContext context, Widget child,
            ImageChunkEvent loadingProgress) {
          if (loadingProgress == null) return child;
          return Center(
            child: CircularProgressIndicator(
              value: loadingProgress.expectedTotalBytes != null
                  ? loadingProgress.cumulativeBytesLoaded /
                      loadingProgress.expectedTotalBytes
                  : null,
            ),
          );
        },
      ),
    );
  }

【讨论】:

    【解决方案2】:

    移除高度限制,然后
    尝试将fit: BoxFit.cover 替换为BoxFit.fitHeightBoxFit.fill

    【讨论】:

      【解决方案3】:

      LayoutBuilder 只给你 约束 父母传递给孩子,类似于100 &lt; width &lt; 200, 300 &lt; height &lt; infinity。此时右侧所有文字的高度还没有确定,因此无法根据此确定图像的高度。

      做到这一点的一种方法是将key分配给每个列表项,在所有内容布局后获取项目高度,并以这些固定高度重建。这将成为一个两次通过的过程,效率较低。

      对此的官方解决方案是IntrinsicHeight,它在概念上做同样的事情,但以更优化的方式。

      这是一个最简单的例子:

      import 'dart:math';
      
      import 'package:flutter/material.dart';
      
      void main() {
        runApp(
          MaterialApp(
            home: App(),
          ),
        );
      }
      
      class App extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            body: ListView.builder(
              itemCount: 10,
              itemBuilder: (context, index) {
                return Card(
                  clipBehavior: Clip.antiAliasWithSaveLayer,
                  // This is where magic happened
                  child: IntrinsicHeight(
                    child: Row(
                      children: [
                        Container(
                          width: 100,
                          decoration: BoxDecoration(
                            image: DecorationImage(
                              image: NetworkImage('https://cataas.com/cat'),
                              fit: BoxFit.cover,
                            ),
                          ),
                        ),
                        Expanded(
                          child: Text(
                            // just put some random text with dynamic height
                            'Text\n' * (Random().nextInt(4) + 4),
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              },
            ),
          );
        }
      }
      

      【讨论】:

      • @Damandroid “对不起,这不起作用”对你没有帮助。
      • 抱歉,这么多天后我已经放弃了,现在改变策略似乎是更好的选择。我现在已经改变了布局。
      【解决方案4】:

      这里的问题是您的描述文本超出了您所需的最大高度。您可以尝试使用height: 70.0 约束您的Container,或者您可以将属性maxLines: 1 添加到您的Text 小部件。

      【讨论】:

      • 谢谢,但这不是问题,这是一项功能。说明不应被剪裁为一行。
      • 所以你想把照片调整到最大高度?
      • 是的,这就是愿望
      • 如果您让图像Containerheight 可能会对您有所帮助。否则尝试给double.infinity
      • 好的.. 尝试使用LayoutBuilder: api.flutter.dev/flutter/widgets/LayoutBuilder-class.html 并使用maxHeight 属性
      【解决方案5】:

      试试这个:

          Column(
            children: [
              Expanded(
                child: Container(
                  width: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.only(topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
                    image: DecorationImage(
                        image: NetworkImage(widget.menuItem.image),
                        fit: BoxFit.cover
                    ),
                  ),
                ),
              ),
            ],
          ),
      

      【讨论】:

      • 这样做时会出现各种渲染错误。
      猜你喜欢
      • 2020-02-08
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 2018-04-09
      • 2013-06-02
      相关资源
      最近更新 更多