Flutter:“RenderFlex 子项具有非零 flex,但传入的高度约束是无界的”

Dol*_*rma 52 dart flutter flutter-layout

ListView当我FutureBuilder用 a包装时,我想在另一个小部件内部有一个小部件Column,以便有一个简单的Row. 我收到此错误:

The following assertion was thrown during performLayout():
I/flutter (13816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (13816): When a column is in a parent that does not provide a finite height constraint, for example, if it is
I/flutter (13816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (13816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (13816): space in the vertical direction.
I/flutter (13816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter (13816): cannot simultaneously expand to fit its parent.
I/flutter (13816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter (13816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter (13816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter (13816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter (13816): constraints provided by the parent.
I/flutter (13816): If this message did not help you determine the problem, consider using debugDumpRenderTree():
Run Code Online (Sandbox Code Playgroud)

我的代码:

The following assertion was thrown during performLayout():
I/flutter (13816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (13816): When a column is in a parent that does not provide a finite height constraint, for example, if it is
I/flutter (13816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (13816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (13816): space in the vertical direction.
I/flutter (13816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter (13816): cannot simultaneously expand to fit its parent.
I/flutter (13816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter (13816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter (13816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter (13816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter (13816): constraints provided by the parent.
I/flutter (13816): If this message did not help you determine the problem, consider using debugDumpRenderTree():
Run Code Online (Sandbox Code Playgroud)

Cop*_*oad 79

像这样将您的Column内部包裹起来ExpandedSizedBox(带有一些height):

Expanded(
  child: Column(...)
)
Run Code Online (Sandbox Code Playgroud)

或者

SizedBox(
  height: 200, // Some height
  child: Column(...),
)
Run Code Online (Sandbox Code Playgroud)

请注意,一个Flex类或子类(如Column)不应该是其他Flex类的子类,并且它们的父类需要是类型Flexible(即继承它,如Expanded),否则Flex-class 将无界(并且无法计算剩余空间)这不会导致直接问题,直到另一个孩子尝试计算和/或填充空间。

  • 请回答为什么会出现该错误信息?什么意思? (2认同)

Bak*_*ker 33

解释

如何Column > Expanded用另一个包装 aExpanded解决错误。

RenderFlex 无界错误

获取"RenderFlex children have non-zero flex but incoming height constraints are unbounded"错误的常见嵌套列扩展层次结构:

Screen
  ? Column
    ? Column
      ? Expanded ? ERROR
Run Code Online (Sandbox Code Playgroud)

发生了什么:

Screen
  ? constraint ? (Screen)
  Column
    Text_A (fixed height: no constraint needed) ? OK
    Column 
      ? constraint ? (unbounded)
      Text_B (fixed height) ? OK
      Expanded: calc. height = unbounded - Text_B ? ERROR
Run Code Online (Sandbox Code Playgroud)

在布局期间, aColumn执行(按顺序):

  • 无界空间中的固定高度(即空/零弹性系数)小部件布局,然后...
  • flex-factor 大小的小部件,从父级(即传入约束)和固定大小的小部件计算剩余空间

Text_A以上是固定高度。它不使用传入约束进行布局。

Expanded不过,它是一个 flex-factor 小部件,在布局固定大小的项目后,根据剩余空间调整自身大小。这需要传入约束(父大小)进行减法:

  parent size (constraint) - fixed-items size = remaining space
Run Code Online (Sandbox Code Playgroud)

第一个Column从设备屏幕获取约束(通过Scaffold等提供)。

但是,第二个Column(嵌套的)位于无限空间中。

无法计算剩余空间:

  unbounded - Text_B = unbounded (error)
Run Code Online (Sandbox Code Playgroud)

为什么嵌套Column无界?

Screen
  ? Column
    ? Column
      ? Expanded
Run Code Online (Sandbox Code Playgroud)

复制自ColumnSDK源文档,步骤1:

/// 1. Layout each child with a null or zero flex factor (e.g., those that are not
///    [Expanded]) with unbounded vertical constraints
Run Code Online (Sandbox Code Playgroud)

第二,嵌套Column

  • 是(显然是第一个)的孩子 Column,并且......
  • 具有零或空弹性系数

第二点是很容易错过/看不见,但Column就是没有一个柔性因素部件。

正在检查 SDK 源...

Column扩展Flex类。

Flex,也不能flex场/柔性因素。只有Flexible类及其子类是弹性因子小部件。

所以第二个Column是在无界约束中布局的,因为它不是一个弹性因子小部件。这些无界约束用于布局Text_B小部件(固定大小或空弹性因子小部件),然后Expanded尝试计算剩余空间。尝试使用无界约束计算剩余空间时....

  unbounded - Text_B = unbounded (error)
Run Code Online (Sandbox Code Playgroud)

Expanded 爆炸

Flexible

超级重复:Flexible, 带有字段/因子flex-factor 小部件flex

Expanded并且SpacerFlexible(我知道的)唯一的子类。

所以Expanded, Spacer, 和Flexible是唯一的 flex-factor 小部件和

Flexible != Flex


修复 - 添加边界

修复小部件树:

Screen
  ? Column
    ? Expanded ? new
      ? Column
        ? Expanded ? OK
Run Code Online (Sandbox Code Playgroud)

为什么这有效...

Screen
  ? constraint ?
  Column
    Text_A ? fixed-size ?
    ? constraint ? (calculated: Screen height - Text_A height)
    Expanded_A
      ? constraint ? (Screen - Text_A)
      Column
        Text_B ? fixed-size ?
        Expanded_B: calc. height = (Screen - Text_A) - Text_B = remaining space ? OK
Run Code Online (Sandbox Code Playgroud)

在这种情况下... 布置固定项后 ( Text_A),计算剩余空间为Expanded_A

parent size (screen) - fixed-items (Text_A) = remaining space
Run Code Online (Sandbox Code Playgroud)

现在Expanded_A有一个定义的空间量。

Expanded_A提供其大小供孩子Column计算Expanded_B布局后的剩余空间使用Text_B

parent size - fixed-items = remaining space
                  ?
(Screen - Text_A) - (Text_B) = remaining space for Expanded_B
Run Code Online (Sandbox Code Playgroud)

现在所有 flex-factor 相对大小的小部件(即Expanded_AExpanded_B)都有有界约束来计算它们的布局大小。

请注意,您可以Flexible在此处与Expanded. 它以与 相同的方式计算剩余空间Expanded。它只是不会强迫孩子适应它的大小,所以如果他们愿意,他们可以更小。

复制/粘贴代码操作:

不好

/// Unbounded constraint: NOT OK
class RenderFlexUnboundedPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Column(
            children: [
              Text('Column > Column > Text_A'),
              Expanded(
                  child: Text('Column > Column > Expanded_A')) // explosions
            ],
          )
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

好的

/// Constraints provided: OK
class RenderFlexPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Text('Column > Text_A'),
          Expanded( // Expanded_A
            child: Column(
              children: [
                Text('Column > Expanded_A > Column > Text_B'),
                Expanded( // Expanded_B
                    child: Text('Column > Expanded_A > Column > Expanded_B'))
              ],
            ),
          )
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 简而言之,“Flex”类或子类(如“Column”)不能是其他“Flex”类的子类,并且它们的父类必须是“Flexible”类型(即继承它),否则,它们是无界的(并且无法计算剩余空间),这不会导致直接问题,直到另一个孩子尝试计算并填充它 (5认同)

小智 17

如果您想解决Render Flex问题,请尝试:

Scaffold(
  body: SingleChildScrollView(
    child: SizedBox(
      height: MediaQuery.of(context).size.height,
      child: Column(
        children: [
Run Code Online (Sandbox Code Playgroud)