将可组合高度调整为与宽度相同

Resize Composable height to be the same as width

我正在尝试在 Jetpack Compose 中实现一个包含 2 列的网格 UI。

我的要求是

这应该如下所示

<-- parent 
    width -->
 ____   ____
|    | |    |
|____| |____|

 ____   ____
|    | |    |
|____| |____|

 ... and more items

我已经通过下面的代码部分地实现了这一点,但是高度似乎没有被“发送”到 children。



// can use this inside a Column or LazyColumn
@Composable
fun TileRow() {
    Row(modifier = Modifier.fillMaxWidth()) {
        Box(modifier = Modifier.weight(1f, fill = true).padding(10.dp)) {
            TestTile()
        }

        Box(modifier = Modifier.weight(1f, fill = true).padding(10.dp)) {
               TestTile()
        }
    }
}

@Composable
fun TestTile (){
    Surface(
            color = Color.Red,
            modifier = Modifier
                    .layout { measurable, constraints ->
                        val placeable = measurable.measure((constraints))
                        //placeable.height = placeable.width // can't resize. height has a private setter
                        layout(placeable.width, placeable.width) {
                            placeable.place(x = 0, y = 0, zIndex = 0f)
                    }
            }.fillMaxSize() // fills the width, but not height, likely due to above layout
    ){
        Column {
            Text(text = "item1")
            Text(text = "item2 to fill",
                    modifier = Modifier
                            .weight(1f)) // this is gone when weight is added
            Text(text = "item3")
        }
    }
}

这会创建以下内容 UI。

看起来 Surface 布局正确,因为下一个 Row 有 space。但是该列似乎没有占据全部高度。这也意味着列项目的 weight() 不起作用。将 weight 修饰符添加到列 children 使它们消失。

如何解决上述问题,以便 children 可以知道高度并达到预期的结果?

作为参考,我使用的是 Jetpack Compose alpha09

更新: 我试过使用 preferredHeight(IntrinsicSize.Max) 并且它似乎工作得更好,但它确实需要用 @ExperimentalLayout 标记代码所以如果还有其他可用选项,我宁愿先不使用它。

根据 TileRow 的宽度自行设置磁贴的约束:

layout { measurable, constraints ->
                val tileSize = constraints.maxWidth / columnCount

                val placeable = measurable.measure(constraints.copy(
                    minWidth = tileSize,
                    maxWidth = tileSize,
                    minHeight = tileSize,
                    maxHeight = tileSize,
                ))

                layout(placeable.width, placeable.width) {
                    placeable.place(x = 0, y = 0, zIndex = 0f)
                }
}

有关完整示例,请参阅 LazyGrid