3

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

Sreekant Shenoy
  • 1,420
  • 14
  • 23
  • Why don't you use a single `LazyRow`? :/ – nglauber Jul 21 '21 at 14:11
  • @nglauber That is the design guideline, have to do it the same way. – Sreekant Shenoy Jul 21 '21 at 14:14
  • Perhaps you could use [LazyVerticalGrid](https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Function1)) – Sandro Kakhetelidze Jul 21 '21 at 14:32
  • @SandroKakhetelidze No, I require the Horizontally scrollable grid. There should be some way to make this work. – Sreekant Shenoy Jul 21 '21 at 14:36
  • 1
    Actually, it has https://developer.android.com/jetpack/compose/lists#lazy-grids – Psijic Jun 08 '22 at 14:33

1 Answers1

3

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))
    }
}
Sreekant Shenoy
  • 1,420
  • 14
  • 23
  • 1
    You can refer [here](https://stackoverflow.com/questions/69608517/scroll-two-lazy-scrollers-together) instead. It would be simpler – Richard Onslow Roper Oct 17 '21 at 20:58
  • 1
    @MARSK Nice, but has animation lag. – Sreekant Shenoy Oct 21 '21 at 15:04
  • No it doesn't on my device. It works quite smooth. Are you trying on an emulator? – Richard Onslow Roper Oct 21 '21 at 16:10
  • I suggested since the modification is specific to `LazyVerticalGrid`, while the link offers all round customisation. – Richard Onslow Roper Oct 21 '21 at 16:11
  • 1
    Okay. Yes, It was on emulator. If it had worked on emulator, it would ensure to work well on low-end devices too. – Sreekant Shenoy Oct 21 '21 at 17:45
  • I wouldn't count on that. Emulators mimic minimal system resources, but they are not able to mimic it efficiently, depending on the hardware of the PC you are running them on. So you cannot expect an emulator to give accurate results of the exact same physical model. I have seen emulators become non-responsive on very-bootup. I have also seen them take minutes to open up the main app launcher (the drawer where all the apps are stored) – Richard Onslow Roper Oct 21 '21 at 19:22
  • Emulators will always be slower. It has to do with compilation and runtime optimizations. – Marco Antonio Jan 17 '23 at 18:50