Search code examples
androidkotlinandroid-jetpack-composelazycolumn

Why Modifier.weight() doesn't work in a LazyColumn


I was trying to create a LazyColumn containing Cards, each containing 3 elements: a Row, a Divider, and another Row. The issue arises when I use Modifier.weight(0.25f) within one of the Rows. I intended the second Row to have a size equal to 1/4 of the first one. However, that Row simply disappears. Why is that? I know I could just fix the size of the second Row as well, but i want to understand why in this way isn't working properly

LazyColumn(modifier){
        items(topTens){
            Column {
                Row(
                    Modifier
                        .height(20.dp)
                        .background(Color.Magenta)
                ) {
                    Text(text = "Prova1")
                }
                Row(
                    Modifier
                        .weight(0.25f, false)
                        .background(Color.Green)
                ) {
                    Text(text = "Prova2")
                }
            }
        }
    }

enter image description here

The problem seems to happen only if I nest rows into Column. If nest columns into row the problem doesnt happen. So if I have somehting like

LazyColumn(modifier=modifier.fillMaxHeight()){
        items(topTens){
            Row {
                Column(
                    Modifier
                        .width(100.dp)
                        .background(Color.Magenta)
                ) {
                    Text(text = "Prova1")
                }
                Column(
                    Modifier
                        .weight(0.25f, false)
                        .background(Color.Green)
                ) {
                    Text(text = "Prova2")
                }
            }}
    }

Everything works as intended and I see 2 Columns.


Solution

  • In this scenario, the issue arises because when a weight is applied in a column scope, the column divides the vertical space remaining after measuring unweighted elements and distributes it according to the weights. However, when a column is a child of a scrollable column, and the calculation of remaining vertical space made by .weight becomes infinite so Jetpack Compose ignores the weight.

    But why doesn't this issue occur when Rows are used instead of Columns?

    • The distinction lies in the fact that columns arrange their items vertically, while rows arrange them horizontally. When a weight is used in a column scope, it divides the vertical space remaining after measuring unweighted child elements, distributing it according to the weight. In contrast, when a weight is used in a Row scope, it only concerns itself with dividing the horizontal space. In this case, the vertical space being infinite is not a problem.

    The solution to this problem is to avoid making the remaining vertical space infinite for the column that having a weight. you can do that by fixing a height for that column.

    Column(Modifier.height(200.dp)) {
                Row(
                    Modifier
                        .height(80.dp)
                        .weight(1f)
                        .background(Color.Magenta)
                ) {
                    Text(text = "Prova1")
                }
                Row(
                    Modifier
                        .weight(0.25f, true)
                        .background(Color.Green)
                ) {
                    Text(text = "Prova2")
                }
            }