🎨 Compose动画过渡 开发实战

📘 第1课 · 动画基础
✨ Compose动画概述 声明式 · 响应式

Jetpack Compose 将动画提升为一等公民。不同于传统命令式动画,Compose 基于状态驱动,只需描述目标状态与动画规格,框架自动处理插值、暂停、取消等复杂逻辑。让开发者专注于“什么”而非“如何”。

动画类别核心API适用场景
💫 基础补间animateFloatAsState / animateColorAsState大小、颜色、透明度变化
🌀 过渡动画AnimatedVisibility / AnimatedContent入场/退场、内容切换
⚡ 高级动画Animatable / AnimationSpec自定义曲线、重复、反向
🧩 手势动画animate*AsState + pointerInput拖拽、滑动、缩放
🧠 声明式动画思想 State → Composable
  • 状态即UI — 动画只是状态的连续变化,UI自动重组。
  • 不可变快照 — 每一帧都基于当前状态快照,无副作用。
  • 线性依赖 — 动画规格(时长、缓动)与状态分离,易于测试。
  • 可组合 — 多个动画通过 updateTransition 或 Animatable 优雅协同。
🎯 核心对比
命令式 ← 手动控制帧
声明式 ← 描述目标状态
动画状态 Animatable 动画规格 AnimationSpec (tween, spring, repeat…) 重组UI @Composable 状态 + 规格 → 驱动每一帧重组
🔁 动画状态 State & remember

动画状态是Compose动画的心脏。常用状态容器:

  • remember { mutableStateOf(...) } — 基础可变状态
  • remember { Animatable(...) } — 面向动画的状态,支持 snap、animateTo
  • animate*AsState — 最简洁,目标值变化自动驱动
  • updateTransition — 管理多个子动画状态
📌 状态驱动示例
val alpha = remember { Animatable(1f) }
// 调用 alpha.animateTo(0f, tween(800))
⚙️ 动画规格 AnimationSpec
规格类型构造参数特点
tweendurationMillis, delay, easing标准补间,最常用
springdampingRatio, stiffness弹性效果,自然回弹
keyframes关键帧时间-值对精确控制路径
repeatable重复模式, 次数循环/往复动画
infiniteRepeatable重复模式, 初始延迟无限循环
📄 实战片段 · 带动画状态与规格
// 声明式动画:大小变化 + 弹性规格
@Composable
fun ElasticBox() {
    var expanded by remember { mutableStateOf(false) }
    val size by animateDpAsState(
        targetValue = if (expanded) 200.dp else 80.dp,
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        ), label = "size"
    )
    Box(
        modifier = Modifier
            .size(size)
            .background(Color(0xFFF5CBA7))
            .clickable { expanded = !expanded }
    )
}
🧩 声明式动画思想 · 一句话: “当状态改变,动画自动发生”
Compose 追踪状态依赖,仅更新变化部分。动画规格决定如何变化,状态决定目标。