动画为何重要
用动效引导用户并带来愉悦体验
动画为何重要 是 CoddyKit 上的免费 Android Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 4 节课。
让动画发挥作用
动画不仅仅是视觉装饰。在优秀的 Android 应用中,动态效果会引导注意力、解释发生了什么变化,并让界面感觉灵敏而生动。
在本课程中,您将学习 Jetpack Compose 的动画 API,从一行代码即可使用的 animate*AsState 辅助函数,到 AnimatedVisibility、过渡效果和基于物理的弹簧动画。
第一课将介绍为什么以及何时应该使用动画,让每个动态效果都有明确的作用。
Compose 以声明式方式实现动画
在 Compose 中,您不需要逐帧手动启动和停止动画。相反,您只需描述一个目标值;每当该值发生变化时,Compose 就会平滑地向它过渡。
这里,方框的颜色由一个布尔状态驱动。点击后状态翻转,颜色会自动平滑变化。
@Composable
fun ColorBox() {
var selected by remember { mutableStateOf(false) }
val color by animateColorAsState(
targetValue = if (selected) Color.Green else Color.Gray,
label = "box-color"
)
Box(
Modifier
.size(120.dp)
.background(color)
.clickable { selected = !selected }
)
}反馈用户操作
动态效果最重要的作用之一是反馈。用户点击按钮或切换开关时,小幅动画可以确认应用已经接收到操作。
瞬间且突兀的变化会让人感觉应用出了问题;150 到 300 毫秒的快速过渡则会让界面更加精致。这里的按钮在按下时会略微缩小。
@Composable
fun PressableButton(onClick: () -> Unit) {
var pressed by remember { mutableStateOf(false) }
val scale by animateFloatAsState(
targetValue = if (pressed) 0.92f else 1f,
label = "press-scale"
)
Button(
onClick = onClick,
modifier = Modifier.graphicsLayer {
scaleX = scale; scaleY = scale
}
) { Text("Tap me") }
}解释状态变化
界面发生变化时,动画可以帮助用户理解刚刚发生了什么。淡入并滑入的项目会让人理解为“新增”;淡出则表示“移除”。
没有动态效果时,内容可能会突然出现或消失,让用户困惑某个内容究竟是出现了、消失了,还是移动了。
@Composable
fun Banner(visible: Boolean) {
AnimatedVisibility(
visible = visible,
enter = fadeIn() + slideInVertically(),
exit = fadeOut() + slideOutVertically()
) {
Text("Saved successfully!")
}
}保持连续性和空间感
动态效果可以保持连续性。卡片展开或元素移动到新位置时,为变化添加动画能让用户保持空间方位感。
Compose 可以使用 Modifier.animateContentSize() 自动为布局变化添加动画,因此方框会随着内容变化平滑地变大或变小。
@Composable
fun ExpandableCard(expanded: Boolean) {
Column(
Modifier
.fillMaxWidth()
.animateContentSize()
.padding(16.dp)
) {
Text("Title", style = MaterialTheme.typography.titleMedium)
if (expanded) {
Text("Here is the longer body that appears when expanded.")
}
}
}时长和时机很重要
优秀的动画应该迅速完成。大多数界面过渡的时长应大约在 150 到 400 毫秒之间。太慢会让应用显得迟钝;太快则让人察觉不到动态效果。
Compose 允许您使用 tween 和 easing 曲线调整时长和节奏。缓动通过加速和减速让动态效果感觉更加自然。
val offset by animateDpAsState(
targetValue = if (open) 0.dp else 200.dp,
animationSpec = tween(
durationMillis = 300,
easing = FastOutSlowInEasing
),
label = "panel-offset"
)不要过度使用动画
动画很有力量,也因此很容易被滥用。过多的动态效果会分散注意力、拖慢用户操作,甚至引起不适。
经验法则:
- 使用动画来传达信息,而不是装饰界面。
- 让过渡短促而含蓄。
- 避免同时为屏幕上的所有内容添加动画。
- 动画播放期间绝不要阻止用户进行操作。
尊重无障碍需求
一些用户由于对动态效果敏感,会在系统设置中启用移除动画。体贴的应用应尊重这一偏好。
您可以读取动画是否被缩放为零,并相应减少或禁用非必要的动态效果。
@Composable
fun rememberReduceMotion(): Boolean {
val context = LocalContext.current
val scale = Settings.Global.getFloat(
context.contentResolver,
Settings.Global.ANIMATOR_DURATION_SCALE,
1f
)
return scale == 0f
}Compose 动画工具箱
Compose 提供了一套分层的动画 API。您将在本课程中逐步接触它们:
animate*AsState- 为单个值添加动画(颜色、大小、浮点数)。AnimatedVisibility- 为出现和消失添加动画。updateTransition- 协调多个值同步变化。AnimatedContent- 在不同内容之间进行交叉淡化。Animatable和spring- 提供基于物理效果的底层控制。
请先从高层 API 开始,只有在需要更多控制时再深入到底层。
动画跟随状态
理解一切的关键思维模型是:在 Compose 中,动画会跟踪状态。当您修改某个值时,动画 API 会在每一帧将界面平滑地插值到新值。
这意味着您很少需要编写时间线。您只需声明“此属性应等于 X”,Compose 就会为您处理过渡期间的每一帧。
@Composable
fun FadingText(highlighted: Boolean) {
val alpha by animateFloatAsState(
targetValue = if (highlighted) 1f else 0.4f,
label = "text-alpha"
)
Text(
"Status",
modifier = Modifier.graphicsLayer { this.alpha = alpha }
)
}快速预热纯 Kotlin
动画会在不同值之间进行插值。从本质上说,这只是数学:从 0 到 1 的分数 t 将起始值和结束值进行混合。这个概念(线性插值,即 lerp)是您编写的每个动画的基础。
下面这段简短的纯 Kotlin 代码展示了 Compose 每秒多次应用的这一概念。
fun lerp(start: Float, end: Float, t: Float): Float =
start + (end - start) * t
fun main() {
for (i in 0..4) {
val t = i / 4f
println("t=$t -> ${lerp(0f, 100f, t)}")
}
}快速检查
Jetpack Compose 中动画的核心思维模型是什么?
回顾:有意义的运动
现在您已经了解了动画为何重要,以及动画背后的模型:
- 运动能够提供反馈、解释变化并保持连续性。
- Compose 动画采用声明式方式,并跟随状态变化。
- 让过渡保持简短(约 150-400 毫秒)且有明确目的;不要过度使用动画。
- 请尊重因无障碍需求而减少动态效果的用户。
- 优先使用高层 API:
animate*AsState、AnimatedVisibility、过渡和弹簧。
接下来:使用 animate*AsState 系列为单个值添加动画。
常见问题解答
「动画为何重要」课时是免费的吗?
是的 — 「动画为何重要」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 4 节课。
「动画为何重要」这节课中我会学到什么?
用动效引导用户并带来愉悦体验 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「动画为何重要」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。