Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

android - Resize Composable height to be the same as width

I am trying to implement a grid UI with 2 columns in Jetpack Compose.

My requirements are

  • Width of each item must be half the parent width (minus padding .etc.)
  • Height must be the same so the item is a square.
  • Inside this I should be able to do other things like use weight in a Column

This should look as below

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

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

 ... and more items

I have part way achieved this with the code below, however the height doesn't appear to be "sent" to the 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")
        }
    }
}

This creates the following UI instead.

current output for code

It appears the Surface laid out correctly, since the next Row has space. But the column appears to not take the full height. This also means the weight() for column items doesn't work. Adding the weight modifier to column children makes them just disappear.

How can I fix the above so the children can know the height and achieve the intended result?

For reference I'm using Jetpack Compose alpha09

UPDATE: I have tried using the preferredHeight(IntrinsicSize.Max) and it seems to work better, but it does require making the code be marked with @ExperimentalLayout so prefer not to use it yet if there's another option available.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Set the constraints for your tile yourself, based on the width of the 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)
                }
}

See LazyGrid for a complete example


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...