我有带有 .horizontalScroll() 的 Row,我需要弹跳动画效果。也就是说,当列表出现时,它会向前滚动一点,然后返回。同时,我需要在返回滚动时有一个弹簧效果。 这是我的实现:
val scrollState = rememberScrollState()
val coroutineScope = rememberCoroutineScope()
val bounceDistance = 150
LaunchedEffect(Unit) {
val animatable = Animatable(scrollState.value.toFloat())
coroutineScope.launch {
animatable.animateTo(
targetValue = bounceDistance.toFloat(),
animationSpec = tween(
durationMillis = 200,
easing = LinearOutSlowInEasing
)
)
scrollState.scrollTo(animatable.value.toInt())
animatable.animateTo(
targetValue = 0f,
animationSpec = spring(
dampingRatio = 0.4f,
stiffness = Spring.StiffnessLow
)
)
scrollState.scrollTo(animatable.value.toInt())
animatable.animateTo(
targetValue = bounceDistance * 0.3f,
animationSpec = tween(
durationMillis = 400,
easing = LinearOutSlowInEasing
)
)
scrollState.scrollTo(animatable.value.toInt())
animatable.animateTo(
targetValue = 0f,
animationSpec = spring(
dampingRatio = 0.6f,
stiffness = Spring.StiffnessLow
)
)
scrollState.scrollTo(animatable.value.toInt())
}
}
然而,这一切看起来非常不顺利且缓慢。我做错了什么?
附注这是为了向用户提示该组件具有水平滚动功能。
您的代码无法正常工作,因为您在每个动画后手动更新
scrollState.scrollTo
4 次。当 scrollState.scrollTo
更新时,您应该调用 animatable.value
,例如:
val scrollState = rememberScrollState()
val bounceDistance = 150
val animatable = remember { Animatable(0f) }
LaunchedEffect(Unit) {
animatable.animateTo(
targetValue = bounceDistance.toFloat(),
animationSpec = tween(
durationMillis = 200,
easing = LinearOutSlowInEasing
)
)
animatable.animateTo(
targetValue = 0f,
animationSpec = spring(
dampingRatio = 0.4f,
stiffness = Spring.StiffnessLow
)
)
animatable.animateTo(
targetValue = bounceDistance * 0.3f,
animationSpec = tween(
durationMillis = 400,
easing = LinearOutSlowInEasing
)
)
animatable.animateTo(
targetValue = 0f,
animationSpec = spring(
dampingRatio = 0.6f,
stiffness = Spring.StiffnessLow
)
)
}
LaunchedEffect(animatable.value) {
scrollState.scrollTo(animatable.value.toInt())
}
您可以使用
tween
动画规范和 EaseOutBounce 缓动,而不是手动制作弹跳动画:
animatable.animateTo(
targetValue = bounceDistance.toFloat(),
animationSpec = tween(
durationMillis = 200,
easing = LinearOutSlowInEasing
)
)
animatable.animateTo(
targetValue = 0f,
animationSpec = tween(
durationMillis = 1000,
easing = EaseOutBounce
)
)