OnScrolled in LazyColumnFor ( Jetpack Compose )

2k views Asked by At

Has anyone found an equivalent of onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) in LazyColumnFor?

3

There are 3 answers

1
Mohammad Sianaki On

with 1.0.0-alpha12 It should be what you want:

    val scrollCallback = object : ScrollCallback {
    override fun onCancel() {
        super.onCancel()
    }

    override fun onScroll(scrollDistance: Float): Float {
        return super.onScroll(scrollDistance)
    }

    override fun onStart(downPosition: Offset) {
        super.onStart(downPosition)
    }

    override fun onStop(velocity: Float) {
        super.onStop(velocity)
    }
}
LazyColumnFor(
    modifier = Modifier.scrollGestureFilter(scrollCallback, Orientation.Vertical),
    items = listOf("")
) { item ->

}
0
Patryk Kubiak On

You can get the position of a first item by adding an onGloballyPositioned https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/OnGloballyPositionedModifier option to the first item's modifier.

It returns:

  • an initial position after layout creation
  • an updated position every time during a scroll event

The LayoutCoordinates object inside the lambda let you get:

  • positionInParent()
  • positionInRoot()
  • positionInWindow()

To get an x or y from the LazyColumn/LazyRow you can use this part of code:

        val initialLayoutY: MutableState<Float?> = rememberSaveable { mutableStateOf(null) }
        Text(
            text = "Lorem",
            modifier = Modifier.onGloballyPositioned { layoutCoordinates ->
                if (initialLayoutY.value == null) {
                    initialLayoutY.value = layoutCoordinates.positionInRoot().y
                }

                val currentTextLayoutY: Float = layoutCoordinates.positionInRoot().y
                val currentLazyListY: Float = initialLayoutY.value!! - currentTextLayoutY
                Log.e("Lazy Column y", currentLazyListY.toString())
            }
        )

Unfortunately, it skips a lot of values during fast scrolling. Here is a result:

Result from onGloballyPositioned function

0
Gabriele Mariotti On

It is not exactly onScrolled.

You can use LazyListState#isScrollInProgress to check if the list is currently scrolling by gesture, fling or programmatically or not.

val itemsList = (0..55).toList()

val state = rememberLazyListState()
val scrollInProgress: Boolean by remember {
    derivedStateOf {
        state.isScrollInProgress
    }
}

if (scrollInProgress){
    //....do something
}

LazyColumn(state = state) {
    items(itemsList) {
        Text(".....")
    }
}