Skip to content

Instantly share code, notes, and snippets.

@rkam88
Last active September 12, 2023 11:53
Show Gist options
  • Save rkam88/5a5213f9f9289551be848c0023175d69 to your computer and use it in GitHub Desktop.
Save rkam88/5a5213f9f9289551be848c0023175d69 to your computer and use it in GitHub Desktop.
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.calculateTargetValue
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@Composable
private fun rememberSnapFlingBehavior(state: LazyListState): FlingBehavior {
val flingSpec = rememberSplineBasedDecay<Float>()
return remember {
object : FlingBehavior {
override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
val firstItem = state.layoutInfo.visibleItemsInfo.first()
/** Current offset of the first visible element from the screen's start */
val firstItemOffset = -firstItem.offset.toFloat()
/** Target offset that would be reached by default */
val targetOffset = flingSpec.calculateTargetValue(
initialValue = firstItemOffset,
initialVelocity = initialVelocity
)
/** The element's final visibility rate: 0 - hidden, 1 - fully visible */
val visibilityRate = 1 - (targetOffset / firstItem.size)
val scrollDistance = if (visibilityRate > 0.5f) {
/** Scroll to the left, up to the current element's start */
-firstItemOffset
} else {
/** Scroll to the right, up to the next element */
firstItem.size - firstItemOffset
}
/** Scrolling with animation up to target value */
var consumedScrollDistance = 0f
Animatable(0f)
.animateTo(
targetValue = scrollDistance,
initialVelocity = initialVelocity,
) {
consumedScrollDistance += scrollBy(value - consumedScrollDistance)
}
if (consumedScrollDistance < scrollDistance) {
scrollBy(scrollDistance - consumedScrollDistance)
}
return 0f
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment