如何通过读取子约束使行的子级具有相同的高度

sha*_*mir 4 constraints dart flutter flutter-layout

我有一个带有委托的 SliverList,该委托为每个项目返回 Row 。设计需要这样的结果:

所需布局

这两个孩子是文本和图像。图像是 BoxFit.cover,我使用 Flex 为它们提供所需的宽度比。仅当高度大于或等于宽度边界时(以使其至少保持正方形),我才需要图像边界高度与文本高度匹配。

第一个解决方案是使用 LayoutBuilder 读取图像宽度的约束,并将图像放入 ConstrainedBox 中,minHeight 为 LayoutBuilder->constraints->maxWidth。

LayoutBuilder(
  builder: (context, constraints) => ConstrainedBox(
    constraints: BoxConstraints(
        minHeight: constraints.maxWidth,
        maxHeight: constraints.maxWidth),
    child: CachedNetworkImage(
        imageUrl: "https://via.placeholder.com/400x300",
        fit: BoxFit.cover,
      ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到文本长于图像宽度,此时图像仍然是正方形并且不会拉伸到整个行高:

图像高度未填满行高

第二个解决方案是将 Row 包装在 IntrinsicHeight 小部件中。但这意味着我无法在其中使用 LayoutBuilder 。所以我删除了布局构建器,现在我无法访问设置图像最小高度的约束。图像可以很好地拉伸以填充整个行高度。直到文本太短,导致图像高度低于其宽度:

在此输入图像描述

如何构建此设计以响应可变文本高度?

Yan*_*Yan 14

只需用 IntrinsicHeight 包裹 Row

  
固有高度(
  孩子:行(
    crossAxisAlignment:CrossAxisAlignment.stretch,
    孩子们: [...]
  )
)


use*_*613 7

这可以巧妙地使用来完成Stack,因为 的大小Stack将与其非定位子项相匹配,因此它将自动匹配您的Text小部件。然后使用一个Positioned小部件来显示图像 - 设置它的topbottomto0使其垂直拉伸,设置right: 0使其对齐,并给它一个固定的宽度。

使用堆栈的演示

示例源代码:

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flutter Demo")),
      body: ListView(
        children: [
          for (int i = 8; i < 40; i += 6)
            Stack(
              children: [
                Padding(
                  padding: EdgeInsets.only(right: 100),
                  child: Text("Lorem ipsum " * i),
                ),
                Positioned(
                  top: 0,
                  bottom: 0,
                  right: 0,
                  width: 100,
                  child: Container(color: Colors.primaries[i % 10]),
                ),
              ],
            ),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

您在评论中提到,您希望强制执行“最低高度”。Stack您可以通过放置一个不可见的 ,轻松地在 中做到这一点SizedBox,例如:

Stack(
  children: [
    Padding(
      padding: EdgeInsets.only(right: 100),
      child: Text("Lorem ipsum " * i),
    ),
    SizedBox(height: 100), // this forces minimum height
    Positioned(
      top: 0,
      bottom: 0,
      right: 0,
      width: 100,
      child: Container(color: Colors.primaries[i % 10]),
    ),
  ],
),
Run Code Online (Sandbox Code Playgroud)

结果:

演示