关于 compose-animations
面向 Jetpack Compose 开发者的动画 API 选择与评审技能,依据动画目标和生命周期推荐合适 API,并强调内容身份与性能处理。
主要功能
- 01按动画需求选择 Compose API
- 02区分状态动画与手势动画
- 03检查动画生命周期与内容身份
- 04提供性能和测试建议
适用场景
- 01为显示或隐藏界面选择动画
- 02协调多个状态驱动的动画值
- 03审查 AnimatedContent 的内容切换
- 04排查逐帧动画的布局或绘制性能
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ chrisbanes/ skills --skill compose-animations安装后在 Claude Code 中输入/compose-animations确认已加载。
附带文件references/animated-content.md
详细介绍
Compose:动画
核心原则
选择能够表达动效及其生命周期的最简 API。
流程
- 明确任务:显示或隐藏子树、动画化单个值、协调由同一状态驱动的多个值、调整内容大小、切换内容,或处理用户驱动的动效。
- 从表格中选择相应的 API。优先使用目标状态 API;只有在需要手势、处理中断或命令式控制时,才使用
Animatable。 - 检查生命周期:alpha 动画会让内容继续参与组合;
AnimatedVisibility则会在退出动画结束后移除内容。需要卸载内容时,不要使用淡出效果。 - 对于
AnimatedContent,从内容 lambda 的目标值渲染内容;只有当视觉身份与载荷相等性不一致时,才选择contentKey。在不同项目之间切换时,将目标值保留为身份(默认行为),或使用稳定的项目 ID 作为键;不要将不同项目合并为共享的存在性键或分支键。在评审中,指出任何捕获外部目标状态的渲染表达式,并建议在该处使用 lambda 的目标值。如果测试必须验证过渡身份,请在重叠期间检查退出和进入的内容;只检查稳定后的目标内容会遗漏共享身份问题。有关状态持有者的详细信息,请参阅 AnimatedContent 身份。 - 当动画化的
State以帧率变化时,将其放在布局或绘制块修饰符中;更深入的诊断请参阅 Compose 性能。 - 对于由 Navigation Compose 管理的目标页面切换,使用 Navigation Compose 过渡;对于基于美术素材的动效,使用专用库。
- 当 API、生命周期和内容身份都与 UI 相符、没有更简单的适用 API,且相关行为已验证时,即可结束。
API 选择
| 需求 | 首选 |
|---|---|
| 根据进入/退出语义显示或隐藏子树 | AnimatedVisibility |
| 单个值随状态变化 | animate*AsState |
| 多个值随同一个布尔值、枚举或密封状态变化 | rememberTransition 加子动画 |
| 子项大小发生变化 | Modifier.animateContentSize() |
| 不同的可组合树填充同一区域 | AnimatedContent;简单场景使用 Crossfade |
| 拖动、滑动、处理中断或命令式控制 | Animatable |
当默认动效不合适时,使用 AnimationSpec;当多个动画需要在工具中清晰区分时,为它们指定不同的 label。
val width by animateDpAsState(
targetValue = if (expanded) 200.dp else 56.dp,
animationSpec = spring(dampingRatio = 0.7f),
label = "fabWidth",
)
对于必须保持同步的值,应在同一个 transition 上定义它们,而不是分别调用多个独立的 animate*AsState:
val transition = rememberTransition(targetState = phase, label = "phase")
val alpha by transition.animateFloat(label = "alpha") { target ->
if (target == Phase.Visible) 1f else 0f
}
val offset by transition.animateDp(label = "offset") { target ->
if (target == Phase.Visible) 0.dp else 24.dp
}
对于动画填充,当颜色每帧都会更新时,优先使用 drawBehind { drawRect(color.value) },而不是值形式的 background。对于 API 选择不明确的情况,请先参阅官方选择动画 API指南;重复循环使用 rememberInfiniteTransition,可寻址或由测试控制的进度使用 SeekableTransitionState。
不适用此技能的情况
- 对于副作用时序或由点击启动的任务,请使用 Compose 状态与副作用。
- 对于深入诊断状态读取或重组问题,请使用 Compose 性能。
评论
支持 Markdown