Thread
#compose
    Justin Yue

    Justin Yue

    1 year ago
    I have a similar issue found in this thread where I am inserting a
    LazyVerticalGrid
    inside a
    Column
    with a scroll state, so I now know that I can't nest composables scrolling in the same direction. However, I'm only using
    LazyVerticalGrid
    since the cells can be adaptive, and I don't need its scroll functionality. Is there a way to create a composable that can replicate LazyVerticalGrid's adaptive functionality and removing the scrolling?
    Albert Chang

    Albert Chang

    1 year ago
    What do you mean by "adaptive"? I think you can easily create a grid layout by using multiple Rows and setting
    Modifier.weight(1f)
    on each cell.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Yea, the only interesting part of lazy lists’ functionality is related to scrolling. The non-lazy versions of those layouts are more trivial.
    Justin Yue

    Justin Yue

    1 year ago
    Given a dp size, I think
    LazyVerticalGrid
    can determine how many columns and rows to create for a list of composables while meeting that minimum dp size, and I wanted to replicate that. I honestly forgot that I can create custom layouts, so I ended up going that route today. My solution is not perfect, but I'll keep working on it and am open to feedback.
    // Inspired by:
    // <https://github.com/android/compose-samples/blob/main/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Grid.kt>
    @Composable
    fun VerticalGrid(
        minWidth: Dp,
        rowPadding: Dp = 0.dp,
        modifier: Modifier = Modifier,
        content: @Composable () -> Unit
    ) {
        Layout(
            content = content,
            modifier = modifier
        ) { measurables, constraints ->
            val numOfColumns = constraints.maxWidth / minWidth.roundToPx()
            val columnWidth = constraints.maxWidth / numOfColumns
    
            Log.i(TAG, "numOfColumns: $numOfColumns, maxWidth: ${constraints.maxWidth} columnWidth: $columnWidth")
    
            val itemConstraints = constraints.copy(
                minWidth = minWidth.value.toInt(),
                maxWidth = columnWidth
            )
    
            val placeables = measurables.map { measurable -> measurable.measure(itemConstraints) }
            val columnHeights = Array(placeables.size) { i -> (i / numOfColumns) * 96.dp.roundToPx() + (rowPadding.roundToPx() * (i/numOfColumns))}
    
            for (i in columnHeights.indices) {
                Log.d(TAG, "columnHeights index $i - ${columnHeights[i]}")
            }
    
            var height = (columnHeights.maxOrNull() ?: constraints.minHeight )
                .coerceAtMost(constraints.maxHeight)
    
            Log.d(TAG, "before: $height")
            if (height < constraints.maxHeight) {
                Log.d(TAG, "num of rows: ${columnHeights.lastIndex/numOfColumns}")
                height *= (columnHeights.lastIndex/numOfColumns)
            }
            Log.d(TAG, "after: $height vs max height: ${constraints.maxHeight}")
    
            layout(constraints.maxWidth, (height * 0.85).toInt()) {
                placeables.forEachIndexed { index, placeable ->
                    val row = index / numOfColumns
                    val column = index % numOfColumns
    
                    Log.i(TAG, "row: $row")
    
                    placeable.placeRelative(
                        x = column * columnWidth,
                        y = columnHeights[index]
                    )
                }
            }
        }
    }