Search code examples
androidkotlinandroid-jetpack-compose

JetpackCompose: Spacer with "weight(1f)" does not work in Column


I expect to use compose to implement the following style:

expected

The above screenshot effect is implemented using flex in HTML,and I try to use Jetpack Compose to reproduce this effect,but I got:

compose

BottomText should be at the bottom of the card (as shown in the picture below), but Spacer does not seem to work:

expected

Here is my compose code:

@Composable
@Preview(showBackground = true)
fun TestPreview() {
    LazyColumn {
        item {
            TestItem("kkk")
        }
        item {
            TestItem("k".repeat(200))
        }
    }
}

@Composable
fun TestItem(content: String) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.Cyan)
            .border(1.dp, Color.Black)
            .padding(10.dp)
    ) {
        Box(
            modifier = Modifier
                .size(80.dp)
                .background(Color.Red)
        )

        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Green),
            verticalArrangement = Arrangement.SpaceBetween
        ) {
            Text("123", fontSize = 18.sp, fontWeight = FontWeight.Bold)
            Text("Content: $content")

            Spacer(modifier = Modifier.weight(1f))

            Text("Bottom Text", modifier = Modifier.background(Color.Yellow))
        }
    }
}

how to fix it?

expected


Solution

  • The issue in your code is that the Column is not being able to fillMaxSize due to less content and hence, weight modifier won't work. You need to provide some minimum height in Column.

    So, if your Box height is static(the red one), then you can apply minimum height in Column content and remove Spacer with weight and for fixing width issue in Bottom Text, you can use fillMaxWidth modifier:

    @Composable
    fun TestItem(content: String) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.Cyan)
                .border(1.dp, Color.Black)
                .padding(10.dp)
        ) {
            Box(
                modifier = Modifier
                    .size(80.dp)
                    .background(Color.Red)
            )
    
            Column(
                modifier = Modifier
                    .heightIn(min = 80.dp)
                    .fillMaxSize()
                    .background(Color.Green),
                verticalArrangement = Arrangement.SpaceBetween
            ) {
                Text("123", fontSize = 18.sp, fontWeight = FontWeight.Bold)
                Text("Content: $content")
    
                Text("Bottom Text", modifier = Modifier.fillMaxWidth().background(Color.Yellow))
            }
        }
    }
    

    enter image description here

    Moreover, if you want to align 123 text and content text then you will have to wrap them in separate Column as parent Column has vertical alignment as SpaceBetween