"RenderStack object was given an infinite size during layout" 当使用 Positioned inside a Stack 时

"RenderStack object was given an infinite size during layout" when using Positioned inside a Stack

我正在创建一个在 Container 中显示 Stack 的小部件。 Stack 内部有一个 Positioned 小部件内的动态 Column,它将 Column 粘贴到 Bottom

我正在尝试将 Stack 包装在 SingleChildScrollView 中,如果动态 Column 将有很多子项,它将能够滚动。

但是在我添加滚动视图后,我收到了这个错误信息:

RenderStack object was given an infinite size during layout.

滚动视图没有高度,它将为其子项使用无限高度。因此,如果您需要,堆栈应该包裹在一个已知高度的 sizedBox 中。如果您希望堆栈填满屏幕,请完全删除 singleChildScrollview。如果您希望堆栈可以从内部滚动。只需在堆栈中添加 SingleChildScrollView

return Scaffold(
      body: Container(
        color: Colors.blue[100],
        child: Stack(
          children: [
            Positioned.fill(child: SingleChildScrollView(child: MyColumn()))
          ],
        ),
      ),
    );

编辑 1: 好的,问题是布局本身。由于您只使用堆栈来定位图像。你知道图像的宽度和高度,背景形状填充所有项目。我们可以

仅将堆栈隔离到图像,并使用填充和一些计算以类似方式构建布局。

然后在普通列中呈现其他所有内容

我的实现https://dartpad.dev/230b14d8f0b22b45929a75c208786257

来自 RenderStack 文档:

First, the non-positioned children (those with null values for top, right, bottom, and left) are laid out and initially placed in the upper-left corner of the stack. The stack is then sized to enclose all of the non-positioned children. If there are no non-positioned children, the stack becomes as large as possible.

由于所有 Stack 的 children 都已定位,Stack 将匹配 SingleChildScrollView 传递的最大大小限制。此尺寸具有无限高,因此 Stack 也被迫具有无限高。

要解决这个问题,您需要找到另一种方法来完成您想要的。想到的一个选项涉及 ConstrainedBox 提供最小高度(从 LayoutBuilder 获得)、non-positioned ColumnbottomCenter 对齐Stack 本身。这类似于 SingleChildScrollView 文档中的第一个代码示例:

LayoutBuilder(
  builder: (context, constraints) {
    return SingleChildScrollView(
      child: ConstrainedBox(
        // This ensures that the Stack fills the entire viewport,
        // even if the Column is small.
        constraints: BoxConstraints(
          minHeight: constraints.maxHeight,
        ),
        child: Stack(
          // Place the only non-positioned child (the column) at the bottom
          alignment: Alignment.bottomCenter,
          children: [
            Column(
              mainAxisSize: MainAxisSize.min,
              children: [ /* ... */ ]
            )
          ]
        )
      )
    );
  }
)