refactor: 优化年份视图切换动画,使用 Animatable 精确控制

- 用 Animatable + LaunchedEffect 替换 animateFloatAsState
  实现滑出/滑入分阶段动画序列(先滑出再滑入)
- 统一缩放/淡入淡出动画时长为 350ms
- 底部卡片滑出偏移从 200.dp 增加到 300.dp

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xfy 2026-06-01 13:47:36 +08:00
parent f34e34e5ae
commit be023a00a9

View File

@ -6,6 +6,7 @@ import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
@ -194,11 +195,11 @@ fun CalendarMonthView(
val enter = scaleIn(
initialScale = 0.85f,
animationSpec = tween(350, easing = FastOutSlowInEasing)
) + fadeIn(tween(250, easing = FastOutSlowInEasing))
) + fadeIn(tween(350, easing = FastOutSlowInEasing))
val exit = scaleOut(
targetScale = 0.85f,
animationSpec = tween(250, easing = FastOutSlowInEasing)
) + fadeOut(tween(200, easing = FastOutSlowInEasing))
animationSpec = tween(350, easing = FastOutSlowInEasing)
) + fadeOut(tween(350, easing = FastOutSlowInEasing))
enter togetherWith exit
},
modifier = Modifier.fillMaxSize()
@ -582,11 +583,17 @@ private fun BottomCardArea(
dragRangeMinPx
}
val slideProgress by animateFloatAsState(
targetValue = if (isYearView) 1f else 0f,
animationSpec = tween(350, delayMillis = 100, easing = FastOutSlowInEasing),
label = "bottomCardSlide"
)
val slideAnim = remember { Animatable(if (isYearView) 1f else 0f) }
LaunchedEffect(isYearView) {
if (isYearView) {
slideAnim.animateTo(1f, tween(200))
} else {
slideAnim.snapTo(1f)
delay(200)
slideAnim.animateTo(0f, tween(150))
}
}
val slideProgress = slideAnim.value
var lastLoggedSlide by remember { mutableStateOf(-1f) }
SideEffect {
if (kotlin.math.abs(lastLoggedSlide - slideProgress) > 0.001f) {
@ -620,7 +627,7 @@ private fun BottomCardArea(
onExpandDragEnd = { viewModel.onExpandDragEnd() },
dragRangePx = dragRangePx,
modifier = modifier
.offset(y = with(density) { (slideProgress * 200).dp })
.offset(y = with(density) { (slideProgress * 300).dp })
.alpha(1f - slideProgress)
)
}