将可组合高度调整为与宽度相同
Resize Composable height to be the same as width
我正在尝试在 Jetpack Compose 中实现一个包含 2 列的网格 UI。
我的要求是
- 每个项目的宽度必须是 parent 宽度的一半(减去填充等)
- 高度必须相同,所以项目是正方形。
- 在里面我应该可以做其他事情,比如在
Column
中使用 weight
这应该如下所示
<-- 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
我正在尝试在 Jetpack Compose 中实现一个包含 2 列的网格 UI。
我的要求是
- 每个项目的宽度必须是 parent 宽度的一半(减去填充等)
- 高度必须相同,所以项目是正方形。
- 在里面我应该可以做其他事情,比如在
Column
中使用
weight
这应该如下所示
<-- 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