Search code examples
androidkotlinandroid-jetpack-composeandroid-jetpack

How to level the height of items in LazyVerticalGrid?


I'm using LazyVerticalGrid to display list of items.

LazyVerticalGrid(
            cells = GridCells.Fixed(2),
            modifier = Modifier.fillMaxSize(),
            state = listState,
            content = {
                    Box(modifier = boxModifier) {
                        ProductItemView(
                            item = items[index]
                        )
                    }
                }
            }
        )

Sometimes some of my items are higher than the items next to them (attachemnt) enter image description here

How can I adjust the height of the all items? Or should I use something other than VerticalGrid()?


Solution

  • If you give a fixed height to your Composables you might end up Composables that don't display some part of your child composables, in your case it might be Text composable.

    First and easy way is to set a minimum height Modifier.heightIn(min = 200.dp), this might leave space below or above your composable depending on your Box alignment, and if your Composables are taller than 200.dp it will have the same effect you have now, so it's not or adding any fixed height is not enough.

    Better way is to use onTextLayout to get Text's line count and height to add smaller number of lines as padding as

    @Composable
    fun GridSnackCardWithTitle(
        modifier: Modifier = Modifier,
        snack: Snack,
    ) {
        Column(
            modifier = modifier
                .heightIn(min = 200.dp)
                .shadow(1.dp, shape = RoundedCornerShape(5.dp))
                .background(Color.White),
    
            ) {
    
            val density = LocalDensity.current.density
    
            Image(
                contentScale = ContentScale.None,
                modifier = Modifier
                    .fillMaxWidth()
                    .aspectRatio(1f)
                    .clip(RoundedCornerShape(8.dp))
                    .clickable { },
                painter = rememberImagePainter(
                    data = snack.imageUrl,
                    builder = {
                        placeholder(drawableResId = R.drawable.placeholder)
                    }
                ),
                contentDescription = null
            )
    
            Spacer(modifier = Modifier.height(4.dp))
            var padding by remember { mutableStateOf(0.dp) }
            Text(
                modifier = Modifier.padding(start = 4.dp, end = 4.dp, bottom = padding),
                text = "Snack ${snack.name}",
                fontSize = 20.sp,
                onTextLayout = {
                    val lineCount = it.lineCount
                    val height = (it.size.height / density).dp
    
                    println("lineCount: $lineCount, Height: $height")
                    padding = if (lineCount > 1) 0.dp else height
                }
            )
            
        }
    }
    

    Result

    enter image description here