Skip to content

Instantly share code, notes, and snippets.

@shohiebsense
Created June 29, 2022 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shohiebsense/9f019b52feda441a79bec5185a5afc9c to your computer and use it in GitHub Desktop.
Save shohiebsense/9f019b52feda441a79bec5185a5afc9c to your computer and use it in GitHub Desktop.
Jetpack Compose Bounce, or Elastic, or Velocity Physics Scrolling. Credit to Android Codelabs; Jetpack Compose Animation
fun Modifier.velocityBouncePhysicsList(
scrollState: ScrollState): Modifier = composed {
if(scrollState.value == 0 || scrollState.value == scrollState.maxValue){
val offsetY = remember { Animatable(0f) }
pointerInput(Unit) {
val decay = splineBasedDecay<Float>(this)
coroutineScope {
while (true) {
val pointerId = awaitPointerEventScope { awaitFirstDown().id }
offsetY.stop()
val velocityTracker = VelocityTracker()
awaitPointerEventScope {
verticalDrag(pointerId) { change ->
val yChangePosition = change.positionChange().y
if((yChangePosition > 0 && scrollState.value == scrollState.maxValue) || yChangePosition < 0 && scrollState.value == 0){
return@verticalDrag
}
val horizontalDragOffset = offsetY.value + yChangePosition
launch {
offsetY.snapTo(horizontalDragOffset)
}
velocityTracker.addPosition(change.uptimeMillis, change.position)
change.consumePositionChange()
}
}
val velocity = velocityTracker.calculateVelocity().y
val targetOffsetY = decay.calculateTargetValue(offsetY.value, velocity)
offsetY.updateBounds(
lowerBound = -size.height.toFloat(),
upperBound = size.height.toFloat()
)
launch {
offsetY.animateTo(targetValue = 0f, initialVelocity = velocity)
}
}
}
}.offset { IntOffset(0, offsetY.value.roundToInt()) }
} else {
this
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment