动画不是炫技,它是用户体验的一部分。按钮点击没反馈、页面跳转太生硬,用户会觉得 App“不跟手”。
Android 动画经历过几次演进:View 动画 → 属性动画 → MotionLayout。今天把核心路径串一遍。
一、属性动画 ValueAnimator + ObjectAnimator
属性动画改变的是对象的真实属性,而不是只做视觉位移。
ObjectAnimator.ofFloat(view, "translationX", 0f, 200f).apply {
duration = 300
interpolator = AccelerateDecelerateInterpolator()
start()
}
常用属性:
translationX/Y:平移scaleX/Y:缩放rotation:旋转alpha:透明度
注意:动画作用的目标属性必须有 getter/setter,否则不会生效。
二、Interpolator 与 Evaluator
ValueAnimator.ofFloat(0f, 1f).apply {
duration = 1000
interpolator = OvershootInterpolator()
addUpdateListener { animation ->
val value = animation.animatedValue as Float
view.alpha = value
}
start()
}
Interpolator 控制变化节奏,常见的有:
LinearInterpolator:匀速AccelerateDecelerateInterpolator:先加速后减速BounceInterpolator:弹跳效果PathInterpolator:自定义贝塞尔曲线
Evaluator 控制值类型插值,比如 ArgbEvaluator 可以让颜色平滑过渡。
三、MotionLayout:声明式复杂动画
MotionLayout 是 ConstraintLayout 的扩展,用 XML 描述起始和结束状态:
<androidx.constraintlayout.motion.widget.MotionLayout
app:layoutDescription="@xml/scene">
<View android:id="@+id/box" ... />
</androidx.constraintlayout.motion.widget.MotionLayout>
<!-- res/xml/scene.xml -->
<MotionScene>
<Transition app:constraintSetStart="@id/start" app:constraintSetEnd="@id/end">
<OnSwipe app:dragDirection="dragRight" />
</Transition>
</MotionScene>
适合场景:
启动页到首页的过渡
详情页展开/收起
拖拽交互的联动动画
四、Compose 动画
Compose 里推荐用高级 API:
AnimatedVisibility(visible = show) {
Text("Hello")
}
val offset by animateDpAsState(targetValue = if (expanded) 100.dp else 0.dp)
Compose 动画底层也是基于状态驱动,写法更声明式。
五、动画性能 checklist
避免在
onDraw里做逐帧计算属性动画优先使用硬件加速
复杂动画用
RenderThread或MotionLayout列表动画注意复用,不要频繁创建 Animator
小结
属性动画改真实属性,不是伪动画
Interpolator 控制节奏,Evaluator 控制值类型
MotionLayout 适合复杂状态切换
Compose 动画更声明式,但也要避免过度重组
下一篇,我们钻进本地数据层,聊聊 Room 数据库的索引、迁移和性能优化。
参考阅读
引用链接
[1]Property Animation Overview: https://developer.android.com/develop/ui/views/animations/prop-animation
[2]MotionLayout: https://developer.android.com/develop/ui/views/animations/motionlayout