Property Animation——Android中的动画系统,在Android 3.0(API 11)中引入,它在给定的时间间隔内改变对象的真实属性(不仅仅是View)。与过时的View Animation不同,Property Animation改变对象的实际字段——坐标、大小、透明度、颜色——而不仅仅是视觉显示。根据Google Android Developers(2026)的数据,Property Animation被用于前100名Android应用的89%中。关于其他动画类型的更多信息,请阅读动画通用指南。
要点
Property Animation——是Android SDK中的框架(android.animation包),它在指定时间内对任何对象(View、Drawable、自定义类)的任何属性进行动画处理。与只处理View并仅改变视觉表示(matrix transform)的View Animation不同,Property Animation改变对象的实际字段。这意味着在translationX动画之后,对象实际位于新位置,并且点击在新位置被处理。
Property Animation的架构建立在三个关键类上:ValueAnimator——基础值生成器,ObjectAnimator——用于绑定到对象属性的子类,AnimatorSet——用于分组动画的协调器。三者都支持Interpolator(速度曲线)和TypeEvaluator(值之间的插值规则)。
根据Android Performance Patterns(Google, 2025),在正确配置Interpolator且onAnimationUpdate()中没有繁重计算的情况下,Property Animation以高达60 FPS的频率运行。对于复杂动画(3D、物理),在Android 12+中推荐使用RenderThread(RenderNode Animations)。Property Animation仍然是View属性——translationX、rotationY、scaleX、alpha等的动画的主要选择。
ObjectAnimator——Property Animation中最受欢迎的类。它继承自ValueAnimator,并自动使用动画值调用对象指定属性的setter。ObjectAnimator的工作要求对象具有动画属性的公共setter(例如,属性「translationX」的setTranslationX(float))。
import android.animation.ObjectAnimator
import android.view.View
// 用于translationX的ObjectAnimator
val animator = ObjectAnimator.ofFloat(
myView,
"translationX",
0f,
300f
).apply {
duration = 500L
startDelay = 200L
repeatCount = 1
repeatMode = ValueAnimator.REVERSE
interpolator = FastOutSlowInInterpolator()
start()
}
支持的View属性:translationX、translationY、translationZ、rotation、rotationX、rotationY、scaleX、scaleY、alpha、x、y、elevation。ObjectAnimator.ofFloat()用于float属性,ofInt()用于int,ofObject()用于自定义类型(颜色、点)。对于颜色动画,请使用带ArgbEvaluator或HsvEvaluator的ofObject()。
// 具有自定义TypeEvaluator的ObjectAnimator(颜色)
import android.animation.ObjectAnimator
import android.animation.ArgbEvaluator
import android.graphics.Color
val colorAnim = ObjectAnimator.ofObject(
myView,
"backgroundColor",
ArgbEvaluator(),
Color.BLUE,
Color.RED
).apply {
duration = 1000L
repeatCount = ValueAnimator.INFINITE
repeatMode = ValueAnimator.REVERSE
start()
}
// 同时动画多个属性
val scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.5f)
val scaleYAnim = ObjectAnimator.ofFloat(myView, "scaleY", 1f, 1.5f)
val alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1f, 0.5f)
AnimatorListener——用于跟踪动画事件的接口:onAnimationStart、onAnimationEnd、onAnimationCancel、onAnimationRepeat。使用AnimatorListenerAdapter仅重写需要的方法。从Android 12开始,添加了通过suspendAnimationFrame支持协程的Animator.AnimationCallback。
ValueAnimator——Property Animation的基础类,它在指定时间内生成从start到end的动画值。与ObjectAnimator不同,ValueAnimator不绑定到对象——它只计算中间值并通过监听器通知。开发者自己决定如何处理接收到的值:设置View属性、更改Drawable参数、更新onDraw()中的自定义绘制。
import android.animation.ValueAnimator
import android.view.animation.LinearInterpolator
"> ValueAnimator:加载进度动画
val valueAnimator = ValueAnimator.ofFloat(0f, 100f).apply {
duration = 2000L
interpolator = LinearInterpolator()
repeatCount = ValueAnimator.INFINITE
addUpdateListener { animator ->
val progress = animator.animatedValue as Float
progressBar.progress = progress.toInt()
progressText.text = "${progress.toInt()}%"
}
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationRepeat(animation: Animator) {
Log.d("Anim", "Progress animation restarted")
}
})
start()
}
ValueAnimator.ofInt()——用于整数属性(宽度、高度、步数)。ValueAnimator.ofObject()——用于带TypeEvaluator的自定义类型。ValueAnimator.ofPropertyValuesHolder()——用于使用一个计时器并行动画多个属性,与为每个属性使用单独的Animator相比,这节省了资源。
// 带PointEvaluator的ValueAnimator.ofObject
import android.animation.ValueAnimator
import android.graphics.PointF
import android.animation.PointFEvaluator
val pointAnim = ValueAnimator.ofObject(
PointFEvaluator(),
PointF(0f, 0f),
PointF(300f, 500f)
).apply {
duration = 1000L
addUpdateListener { animator ->
val point = animator.animatedValue as PointF
movingView.x = point.x
movingView.y = point.y
}
start()
}
ValueAnimator性能:在60 FPS频率下,onAnimationUpdate每约16.7毫秒被调用一次。避免在监听器内部进行:对象分配(创建一次PointF/RectF)、调用findViewById()、繁重计算(文件I/O、网络)。对于20+个同时元素的动画,在一个Animator中使用PropertyValuesHolder,而不是20个单独的Animator。对于大小变化的动画,仅在动画结束时(通过AnimatorListenerAdapter.onAnimationEnd)使用View.setLayoutParams()。
AnimatorSet——协调器,允许按特定顺序运行多个Animator(ObjectAnimator、ValueAnimator):顺序(playSequentially)、并行(playTogether)、带延迟(after、before、with)。AnimatorSet支持嵌套——AnimatorSet可以包含其他AnimatorSet以用于复杂场景。
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
// AnimatorSet:顺序和并行动画
val fadeIn = ObjectAnimator.ofFloat(myView, "alpha", 0f, 1f)
val slideUp = ObjectAnimator.ofFloat(myView, "translationY", 100f, 0f)
val bounce = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.1f, 1f)
val animatorSet = AnimatorSet().apply {
// 并行:fadeIn + slideUp
play(fadeIn).with(slideUp)
"> 之后:bounce,延迟 200ms
play(bounce).after(200L)
duration = 400L
interpolator = FastOutSlowInInterpolator()
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
Log.d("Anim", "Set completed")
}
})
start()
}
AnimatorSet.Builder提供流畅的API来构建链:with()——并行,before()——之前,after()——之后。AnimatorSet支持cancel()以停止集合中的所有动画。对于复杂场景(25+动画器),使用PropertyValuesHolder——它更高效,因为它使用一个共享计时器而不是每个Animator单独计时器。
| Builder方法 | 描述 | 示例 |
|---|---|---|
| with(Animator) | 与当前动画并行运行 | play(fadeIn).with(slideUp) |
| before(Animator) | 当前动画在指定之前 | play(fadeIn).before(bounce) |
| after(Animator) | 当前动画在指定之后 | play(bounce).after(slideUp) |
| after(Long) | 当前动画之前的延迟 | play(bounce).after(200L) |
Interpolator确定动画速度从0到1的变化曲线。Android提供内置的Interpolator:LinearInterpolator(均匀)、AccelerateDecelerateInterpolator(慢-快-慢)、FastOutSlowInInterpolator(Material Design)、OvershootInterpolator(超出目标)、BounceInterpolator(弹跳)、AnticipateOvershootInterpolator(开始前回拉并超出目标)。自定义Interpolator通过TimeInterpolator实现。
import android.animation.ObjectAnimator
import android.view.animation.BounceInterpolator
import android.view.animation.OvershootInterpolator
import android.view.animation.AnticipateOvershootInterpolator
// BounceInterpolator——末尾弹跳效果
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
duration = 600L
interpolator = BounceInterpolator()
start()
}
// AnticipateOvershoot——回拉,然后超出
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
duration = 500L
interpolator = AnticipateOvershootInterpolator(2.0f)
start()
}
TypeEvaluator——带有evaluate(fraction, startValue, endValue)方法的接口,计算start和end之间的中间值。内置:ArgbEvaluator(颜色int)、FloatEvaluator、IntEvaluator、PointFEvaluator、RectEvaluator。对于自定义数据类型(例如,具有三个字段的自定义类的动画),实现您自己的TypeEvaluator。对于具有相同设置的多个View的动画,使用PropertyValuesHolder——它接受属性名称和相应值的数组。
// ProgressState类的自定义TypeEvaluator
data class ProgressState(val progress: Float, val color: Int)
class ProgressEvaluator : TypeEvaluator<ProgressState> {
override fun evaluate(
fraction: Float,
startValue: ProgressState,
endValue: ProgressState
): ProgressState {
val progress = startValue.progress + fraction * (endValue.progress - startValue.progress)
val color = ArgbEvaluator().evaluate(
fraction, startValue.color, endValue.color
) as Int
return ProgressState(progress, color)
}
}
"> PropertyValuesHolder — 最高性能
val pvh1 = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f)
val pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f)
val pvhAnim = ObjectAnimator.ofPropertyValuesHolder(myView, pvh1, pvh2).apply {
duration = 300L
start()
}
常见问题
View Animation(Tween Animation)仅通过matrix transform改变View的视觉表示,不影响对象的真实属性。在View Animation中的translationX动画之后,元素在视觉上被移动,但点击在原始位置被处理。Property Animation(ObjectAnimator)改变真实属性——动画后,元素物理上位于新位置。
调用animator.cancel()——动画立即停止,最终值不被应用。调用animator.end()——动画进入最终状态并停止。对于AnimatorSet——set.cancel()停止集合中的所有动画。Animator.pause()和resume()在API 19+上可用于临时暂停。
Material Design推荐:FastOutSlowInInterpolator——用于元素的出现和消失,LinearInterpolator——用于加载指示器,OvershootInterpolator——用于强调效果(按钮),BounceInterpolator——用于拉动刷新和弹性元素。对于从屏幕边缘出现的动画,使用AccelerateDecelerateInterpolator。
检查:(1) 对象具有指定属性的公共setter(setPropertyName()),(2) 属性以camelCase写法在「set」后以小写字母开头,(3) setter接受您传递的相同类型(ofFloat → setPropertyName(float))。对于View,所有标准属性(alpha、translationX、rotation等)都有setter。
ObjectAnimator——当您动画单个标准View属性(alpha、translationX、rotation)时。ValueAnimator——当需要从一个监听器更新多个属性、动画非View属性(进度、自定义绘制)或对象没有所需属性的setter时。ValueAnimator更灵活,但需要更多代码进行手动更新。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。