Changing scroll speed on LazyRow

Viewed 133

Looking at the documentation for LazyRow I was wondering if it was possible to reduce the scroll speed, it looks like LazyRow inherits from ScrollState but I can't find anything useful on how to reduce the speed of the scroll

2 Answers

LazyRow doesn't have a parameter to customize scroll speed so you have to do it manually.

You could first capture the scroll gesture something like the below (from google example here ):

@Composable
fun ScrollableSample() {
    // actual composable state
    var offset by remember { mutableStateOf(0f) }
    Box(
        Modifier
            .size(150.dp)
            .scrollable(
                orientation = Orientation.Vertical,
                // Scrollable state: describes how to consume
                // scrolling delta and update offset
                state = rememberScrollableState { delta ->
                    offset += delta
                    delta
                }
            )
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        Text(offset.toString())
    }
}

Then you have to implement the scroll state at your desired speed for the LazyRow by manually changing the LazyRow's state which is one of the LazyRow parameters. you will also have to disable LazyRow userscrolling something like this:

LazyRow(
    ...
    state = yourCustomState,
    userScrollEnabled = false,
    ...
){ ... }

below is a complete working solution:

    var stateIsGood = rememberLazyListState()

    var offset = 0f
    LazyRow(
        modifier =  Modifier
            .scrollable(
                orientation = Orientation.Horizontal,
                // Scrollable state: describes how to consume
                // scrolling delta and update offset
                state = rememberScrollableState { delta ->
                    offset += delta
                    vm.viewModelScope.launch {
                    //dividing by 8 the delta for 8 times slower horizontal scroll, 
                    //you can change direction by making it a negative number
                        stateIsGood.scrollBy(-delta/8)
                    }
                    delta
                }
            ),
        state = stateIsGood,
        userScrollEnabled = false,

        ) {
        item {
            Text(text = "Header")
        }

        // Add 3 items
        items(3) { index ->
            Text(text = "SCROLL ME First List items : $index")
        }

        // Add 2 items
        items(2) { index ->
            Text(text = "Second List Items: $index")
        }

        // Add another single item
        item {
            Text(text = "Footer")
        }
    }

As a shorter alternative to David's Code,

@Composable
fun LazyStack(ssd: Int = 1) { // Scroll-Speed-Divisor
    val lazyStackState = rememberLazyListState()
    val lazyStackScope = rememberCoroutineScope()
    LazyColumn(
        modifier = Modifier.pointerInput(Unit) {
            detectVerticalDragGestures { _, dragAmount ->
                lazyStackScope.launch {
                    lazyStackState.scrollBy(-dragAmount / ssd).log("checkpoint")
                }
            }
        },
        state = lazyStackState,
        userScrollEnabled = false
    ) {...}
}

And yes, LazyStack is short for LazyStackOverflower

Related