Search code examples
androidandroid-jetpack-composeandroid-jetpack-compose-list

Scroll Multiple LazyRows together - LazyHorizontalGrid alike?


How to assign the same scroll state to two LazyRows, so that both row scrolls together?

Jetpack compose lists currently doesn't have LazyHorizontalGrid, So any alternative solution?

Column{
    LazyRow(                                                        
        modifier = Modifier.fillMaxWidth()          
    ) {                                                              
        // My sublist1                                                           
    }
    LazyRow(                                                        
        modifier = Modifier.fillMaxWidth()                         
    ) {                                                              
        // My sublist2                                                          
    }
}                                                               

Trying to implement below:

sample horizontally scroll image


Solution

  • Update: Google has added the component officially - LazyHorizontalGrid.


    I modified the LazyVerticalGrid class, and made it work towards only GridCells.Fixed(n) horizontal grid.

    Here is the complete gist code: LazyHorizontalGrid.kt

    lazyhorizontalgrid

    Main changes

    @Composable
    @ExperimentalFoundationApi
    private fun FixedLazyGrid(
        nRows: Int,
        modifier: Modifier = Modifier,
        state: LazyListState = rememberLazyListState(),
        contentPadding: PaddingValues = PaddingValues(0.dp),
        scope: LazyGridScopeImpl
    ) {
        val columns = (scope.totalSize + nRows - 1) / nRows
        LazyRow(
            modifier = modifier,
            state = state,
            contentPadding = contentPadding,
        ) {
            items(columns) { columnIndex ->
                Column {
                    for (rowIndex in 0 until nRows) {
                        val itemIndex = columnIndex * nRows + rowIndex
                        if (itemIndex < scope.totalSize) {
                            Box(
                                modifier = Modifier.wrapContentSize(),
                                propagateMinConstraints = true
                            ) {
                                scope.contentFor(itemIndex, this@items).invoke()
                            }
                        } else {
                            Spacer(Modifier.weight(1f, fill = true))
                        }
                    }
                }
            }
        }
    }
    

    Code Usage

    LazyHorizontalGrid(
        cells = GridCells.Fixed(2)
    ) {
        items(items = restaurantsList){
            RestaurantItem(r = it, modifier = Modifier.fillParentMaxWidth(0.8f))
        }
    }