> JETPACK COMPOSE 1.7+ 动画大师课

Jetpack Compose
动画全景实战手册
& 生产级代码范式

// 深入掌握现代 Android 开发中的 60FPS 极速流体动效、弹簧物理交互、共享元素形变过渡及自定义 AGSL 运行时着色器。

01. // 基础属性动画 (BASIC_VALUE_ANIMATIONS)

notifications_active
正在同步云端状态
3 个任务等待处理
expand_more
touch_app 交互预览 (鼠标悬停展开)
基础动画示例 (BasicAnimation.kt) Kotlin Compose
var expanded by remember { mutableStateOf(false) }

val cardPadding by animateDpAsState(
    targetValue = if (expanded) 24.dp else 16.dp,
    animationSpec = spring(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessLow
    )
)

AnimatedVisibility(
    visible = expanded,
    enter = expandVertically() + fadeIn(),
    exit = shrinkVertically() + fadeOut()
) {
    // 内容区域平滑展开并附带弹性动画效果...
}
warning

⚠️ 性能陷阱

避免直接使用 animateDpAsState 频繁触发布局测量与重绘。尽可能使用 Modifier.graphicsLayer 承载位移、旋转与缩放,绕过测量与摆放阶段,确保 60FPS 满帧流畅。

02. // 手势交互与弹性物理 (GESTURES_&_SPRING_PHYSICS)

手势拖拽物理 (SwipePhysicsGesture.kt) Kotlin Compose
val offsetX = remember { Animatable(0f) }
val coroutineScope = rememberCoroutineScope()

Modifier.pointerInput(Unit) {
    detectHorizontalDragGestures(
        onDragEnd = {
            coroutineScope.launch {
                offsetX.animateTo(
                    targetValue = 0f,
                    animationSpec = spring(
                        dampingRatio = Spring.DampingRatioMediumBouncy,
                        stiffness = Spring.StiffnessLow
                    )
                )
            }
        },
        onHorizontalDrag = { change, dragAmount ->
            change.consume()
            coroutineScope.launch {
                // 应用阻尼橡皮筋位移计算公式
                offsetX.snapTo(offsetX.value + dragAmount)
            }
        }
    )
}
lightbulb

💡 最佳实践

手势拖拽过程中切勿频繁 launch 新协程。应复用当前作用域,通过 snapTo 紧跟手指运动,仅在松手释放手势时 launch 动画协程触发阻尼弹性复位。

delete_outline archive
touch_app
左滑进行归档
已启用弹簧物理阻尼
swipe 交互预览 (鼠标悬停模拟滑动)

03. // 共享元素与预测性形变 (SHARED_ELEMENTS_&_LOOKAHEAD)

art_track
SharedTransitionLayout 布局引擎
LookaheadScope 坐标自适应映射
view_in_ar 共享元素无缝形变 (悬停预览)
共享元素形变过渡 (SharedElementTransition.kt) Compose 1.7+
SharedTransitionLayout {
    AnimatedContent(targetState = isDetailed) { target ->
        if (!target) {
            ThumbnailCard(
                modifier = Modifier.sharedElement(
                    rememberSharedContentState(key = "image_hero"),
                    animatedVisibilityScope = this
                )
            )
        } else {
            DetailHeader(
                modifier = Modifier.sharedElement(
                    rememberSharedContentState(key = "image_hero"),
                    animatedVisibilityScope = this
                )
            )
        }
    }
}
verified

✨ 核心要点

在 Jetpack Compose 1.7+ 中,LookaheadScope 与 sharedElement 彻底解决了跨容器组件的预测性测量与无缝形变过渡,无需第三方框架即可原生实现。

04. // AGSL 运行时着色器与自定义画布 (AGSL_SHADERS_&_CANVAS)

AGSL 着色器 Modifier (AgslShaderModifier.kt) Android 13+ (API 33)
val shader = remember { RuntimeShader(AGSL_CODE) }
val time by rememberInfiniteTransition().animateFloat(
    initialValue = 0f,
    targetValue = 10f,
    animationSpec = infiniteRepeatable(tween(10000, easing = LinearEasing))
)

Modifier.graphicsLayer {
    shader.setFloatUniform("u_time", time)
    shader.setFloatUniform("u_resolution", size.width, size.height)
    renderEffect = RenderEffect
        .createRuntimeShaderEffect(shader, "composable")
        .asComposeRenderEffect()
}
speed

🚀 硬件加速

通过 AGSL (Android Graphics Shading Language) 编写的着色器直接运行在 GPU 上,完全解放主线程 CPU,极其适合复杂音频频谱波形、液体波纹与赛博发光特效。

05. // 动画 API 选型对比矩阵 (ANIMATION_API_CHEATSHEET)

API 名称 适用场景 性能开销 控制粒度 一句话总结与选型指南
AnimatedVisibility 视图出现 / 消失 (展开, 淡入淡出, 滑入滑出) 低 (Low) 粗 最简单的进入/退出动画封装,开箱即用。
animate*AsState 单一状态值改变 (颜色, Dp, Float, Offset) 低 (Low) 中 状态驱动平滑过渡。高频动画建议配合 graphicsLayer。
Animatable 手势物理拖拽、连续弹性与中断动效 中 (Medium) 极细 协程驱动的底层核心,支持 snapTo 与物理初速度传递。
updateTransition 多属性联动复合动画 (状态机联动) 中 (Medium) 细 统一管理组件的多个动画属性组,保证时间轴完全同步。
LookaheadScope 共享元素、动态尺寸布局与容器形变 低 (GPU) 极细 Compose 1.7+ 原生跨组件平滑插值引擎。