For reasons that have to do with Jetpack Compose input modifiers consuming all MotionEvents, I find myself writing my own scroll routine for a Composable, of which I have access to the ScrollState.
I have figured out everything I need except flinging. I can't see how to apply performFling(initialVelocity) on a ScrollState. All I can find in the docs are ScrollState.scrollTo
and ScrollState.scrollBy
, which aren't so useful with flings, since the scroll destination or size is unknown.
I also can't find a ScrollState listener, similar to onScrollStateChanged(state: Int)
in the old Android world, that fires when scrolling state changes.
Here is what I have in case somebody can point me in the right direction:
var lastY: Float? = null
var velocityTracker: VelocityTracker? = null
fun scroll(event: MotionEvent) {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
velocityTracker = VelocityTracker.obtain()
lastY = event.y
}
MotionEvent.ACTION_UP -> {
lastY = null
velocityTracker?.let {
it.computeCurrentVelocity(1000)
val initialVelocity = it.yVelocity
velocityTracker?.recycle()
coroutineScope.launch {
???? scrollState.PERFORMFLING?(initialVelocity) ????
AND THEN WHEN THE FLING IS FINISHED viewModel.scrollOffset = scrollState.value
}
}
}
else -> {
velocityTracker?.addMovement(event)
lastY?.let {
val scrollAmount = it - event.y
lastY = event.y
coroutineScope.launch {
scrollState.scrollBy(scrollAmount)
viewModel.scrollOffset = scrollState.value
}
}
}
}
}