前奏

我很熟悉dictum

"Constraints go down. Sizes go up. Parent sets position.

我想了解的是"约束"是如何定义的.这只是一个范围("height must be between 30 and infinity"),还是有更复杂的东西?当然,我可以通过阅读Ffltter的代码找到答案,但我还没有到那个阶段.

对于一个非常具体的例子,concrete answer比挥手更有帮助. 因此,为了避免回答含糊不清,请回答以下concrete个例子.

问题

Why does uncommenting the commented-out line trigger an error?
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          // crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text('Hello),
            Text('World),
        ]),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text('How),
            Text('are you?),
        ]),
      ]
    );
  }
}

澄清

以下是提出这个问题的另一种方式.

在三个部分中:

  • "Constraints go down."
  • "Sizes go up."
  • "Parent sets position."

什么是"size"是很清楚的.是Size-class.

"position"是什么也是很清楚的.这一点也有class分(Offset).

  1. this是"constraint"的班级吗?从程序员的Angular 看得见吗?
  2. 当我们取消注释被注释掉的行(从而触发错误)时,该类的实例将如何更改?

推荐答案

小部件的约束由4个doubles、最小和最大宽度、最小和最大高度定义,其中无穷大是一个可能的值.

现在关于您的问题,将CrossAxisAlignment设置为Stretch,会导致传递给子对象的约束在十字轴上为tight.

Flutter 中的tight约束是,父对象仅为其子对象提供一个宽度和高度的大小,因此最小宽度和最大宽度相等,最小高度和最大高度也是如此. 另一方面,loose约束仅设置最大宽度和最大高度,但子对象可以任意小.

当父对象在特定轴上给出一个约束(即looseinfinite)时,子对象必须为该轴返回size,即NOT infinite,否则Ffltter将抛出BoxConstraints forces an infinite height.

例如,如果你有一个Column,它为它的子ListView提供了无限的高度,如果ListView没有被特定的小部件包装,那么它将抛出,因为它试图给父ListView返回无限的高度, 在这种情况下,您可以用Expanded部件包装ListView,也可以用SizedBox部件包装ListView.

在您的示例中,正在发生的情况如下: 您的Column小部件为其2个子对象(2个Rows)提供了以下高度限制

  • 最小高度:0,最大高度:无穷大.

这是loose个限制,所以子元素们可以根据需要 Select 大小. 然后,这Rows个中的每一个都将相同的约束传递给其子部件(2Text个窗口小部件),并且再次,约束是相同的和松散的, 因此,文本小部件可以想要多高就多高.

一旦你把CrossAxisAlignment设置为Stretch,Row向下传递的约束就很紧,这意味着当父Column,询问具有Stretch的子Row,它想要多大时, Row将返回infinite(始终引用高度),这将抛出错误,如前所述,如果父对象设置的约束已经是infinite,则子对象希望在该轴上的大小不能也是infinite.

因此,为了解决这个问题,当子对象为其子对象设置tight个约束时,该子对象的父对象在特定轴上给出infinite个约束, 子部件MUST要么包装在Flex小部件(Expanded,Flexible)中,要么必须具有finite大小(例如,用SizedBox包装它). 因此,对于您的示例,如果您将Stretch行包装在FlexibleExpanded小部件中,您的错误将消失:

 return Column(
  children: [
    Flexible(      /// this fixes your issue
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text('Hello'),
          Text('World'),
      ]),
    ),
    Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Text('How'),
        Text('are you?'),
    ]),
  ]
);

总而言之,如果父Widget在特定轴上给出了infinite个约束,那么子Widget就不能请求在该特定轴上也有infinite的大小,因为如果有多个子Widget,则下一个子小部件将没有任何剩余空间来调整自己的大小. 在这种情况下,子MUST被用sizing窗口小部件或flex窗口小部件Package.

Flutter相关问答推荐

我如何才能收到每天重复的预定通知?

无法让Riverpod Stream发出新值

flutter -当使用SingleChildScrollView包装我的列小部件时,它不会填充整个高度

使用GO_ROUTER在模式内导航

如何正确处理Flutter 翼中使用火基时发生的碰撞?

为什么PUT方法没有发出任何响应?

无法构建AndroidBundle 包或iOS等

在flutter中实现类似3D的可滚动堆叠分页列表

我如何在Android 13中通过Flutter应用程序打开文件(不是图像、视频或音频)?

在 Flutter 中滑动关闭 PageView.builder 时出现问题

带有命名参数的回调函数不起作用

使用 Flutter 和 Dio 将图像上传到 API

Flutter Riverpod 对提供者状态的变化做出react

Flutter:如何在现有布局之上显示圆角布局?

Flutter蓝牙 - 如何通过蓝牙从设备中获取文件?

无状态小部件被奇怪地重建

如何从 Flutter Slider Widget 中移除发光效果?

Flutter - 定义按钮的优雅方式

为什么 Flutter riverpod 直接分配不起作用但方法可以

如何在 flutter 中更改日期 Select 器 colored颜色 ?