为啥 Flutter Container 在其他 Container 中时不遵守其宽度和高度约束

Posted

技术标签:

【中文标题】为啥 Flutter Container 在其他 Container 中时不遵守其宽度和高度约束【英文标题】:Why Flutter Container does not respects its width and height constraints when it is inside other Container为什么 Flutter Container 在其他 Container 中时不遵守其宽度和高度约束 【发布时间】:2019-07-10 02:15:23 【问题描述】:
Container(
  width: 200.0,
  height: 200.0,
  child: Container(
    width: 50.0,
    height: 50.0,
    decoration: BoxDecoration(
      shape: BoxShape.circle,
      color: Colors.red
    ),
  ),
)

我一直试图在 Container 类文档中找到答案,但没有找到。

更新:

搞了半天,才明白问题所在。

布局内的所有视图都必须具有宽度、高度、x 位置和 y 位置。 (适用于androidios、Flutter等)

在我的代码中,内部容器只有一个宽度和高度,因此它不知道从哪里开始绘制。

因此,如果将容器放置在 Alignment 小部件中,则容器将获得 x 位置和 y 位置并且它可以工作。

【问题讨论】:

请将“更新”部分作为答案。它是一个有价值的信息,我可以使用它来解释所有的布局复杂性。谢谢。 感谢您的更新!非常有用的问题和答案 【参考方案1】:

Flutter 中的约束的工作方式与平时有所不同。 小部件本身没有约束。

当您在Container 上指定width/height 时,您并未限制Container。您正在约束 Containerchild

Container 然后将根据其子项的大小调整自身大小。

因此,父小部件始终对如何确定其后代的大小有最终决定权。

如果你想绕过这个,你必须使用Align 小部件:

Container(
  width: 200.0,
  height: 200.0,
  child: Align(
    alignment: Alignment.topLeft,
    child: Container(
      width: 50.0,
      height: 50.0,
      decoration:
          BoxDecoration(shape: BoxShape.circle, color: Colors.red),
    ),
  ),
);

这可能看起来很奇怪和限制。但是,这就是 Flutter 的布局如此强大和可组合的原因。

【讨论】:

您从哪里获得这些知识?我一直在看文档,但我没有找到类似的东西。尤其是这样:“当您在 Container 上指定宽度/高度时,您并没有限制 Container。您正在限制 Container 的子级” 你可以在here找到它。容器将其宽度/高度属性与其约束(如果已设置)结合起来以约束其子级。 这不是特定于容器的。它适用于所有 Flutter 小部件。我不认为有任何关于此的文档,我是通过经验和查看源代码看到的【参考方案2】:

布局内的所有视图都必须有四个约束:

    宽度 身高 X 位置 Y 位置

这适用于Android、IOS、Flutter等

在代码中,内部容器只有一个宽度和高度,因此它不知道从哪里开始绘制,它会获得所有可用空间。

但是,如果内部容器放置在另一个与其子元素对齐的布局小部件中,例如Center。它将获得其 x 和 y 位置。

Container(
   decoration : BoxDecoration(color : Colors.green),
   width: 200.0,
   height: 200.0,
   child: Center(
        child: Container(
          width: 50.0,
          height: 50.0,
          decoration: BoxDecoration(
                      shape: BoxShape.circle,
                       color: Colors.red
                    ),
            ),
        )
)

红色是内容器,绿色是外容器。

【讨论】:

【参考方案3】:

请记住,设置容器的宽度或高度,与同时设置 min-width 和 max-width 或 min-height 和 max-height 相同。

根据文档,您对内部 Container 的情况将是:

如果小部件没有子级和对齐方式,但提供了高度、宽度或约束,则容器会在这些约束和父级约束的组合下尝试尽可能小。

由于您的外部容器为内部容器提供了 minWidth=minHeight=200 约束,因此您的内部容器的大小不能小于 Size(200, 200)。


为了支持 Rémi Rousselet 的回答,Align 小部件与 Center 小部件相同,如果其父级有约束,它将扩展以适应其父级的约束,并将其子级定位在指定的对齐方式中。

如果小部件具有alignment、约束,并且父级提供有界约束,则考虑到这些约束和父级约束的组合,Container 会尝试尽可能小,然后根据alignment 将孩子定位在自身内部。

在这种情况下,外部 Container 有一个 Align 小部件作为子级(对齐)、约束,并且父级提供有界约束,因此在考虑到其约束和父级约束的组合时,它会尝试尽可能小,这是Size(200, 200)

您可能想知道为什么内部容器的大小是50*50,而不是200*200,因为它的父容器(外部容器)指定了minWidth=minHeight = 200。原因是如前所述 Align 小部件将扩展以适应其父约束,因此在这种情况下 Align 小部件将扩展以适应外部 Container 的约束,即它将具有 Size(200, 200) 的大小,并且告诉它的孩子(内部容器),它可以是它想要的任何尺寸,但不能比我的尺寸大,200*200。因此,应该传递给内部Container的外部Container的minWidth和minHeight信息丢失了。

【讨论】:

以上是关于为啥 Flutter Container 在其他 Container 中时不遵守其宽度和高度约束的主要内容,如果未能解决你的问题,请参考以下文章

Flutter BoxDecoration 的背景色覆盖了 Container 的背景色,为啥?

flutter container image FittedBox

Flutter控件——容器控件:Container

Flutter控件——容器控件:Container

为啥 Flutter 文档在创建 Form 时要求使用 GlobalKey 而不是其他类型的键?

Flutter Bottom 被像素溢出,尝试了 Column()、Row()、Container() 等等