Android属性动画

Android动画分为几种:补间动画、属性动画,还有帧动画等。

补间动画并没有真正去改变其属性,当View使用补间动画变换后点击是没有效果的,因为它的真实位置还在原来的地方。

属性动画则是将View的属性进行改变从而实现动画效果。

ValueAnimator

属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。

ValueAnimator内部使用一种时间循环的机制来计算值与值之间的动画过渡。

1
2
3
4
5
6
7
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:repeatCount="1"
android:repeatMode="reverse"/>

ObjectAnimator

ObjectAnimator是ValueAnimator子类,动画所给的对象,他会调用对象对应属性的get/set方法吧属性的值设置给对象的属性,直接实现动画效果。

1
2
3
4
5
6
7
8
9
/**
* 第一个参数:目前空间
* 第二个参数:该控件的属性值
* 第三个参数:属性的开始值
* 第四个参数:属性的结束值
*/
ObjectAnimator anim = ObjectAnimator.ofFloat(view, “alpha”, 0f, 1f);
anim.setDuration(1000);
anim.start();

常用的属性动画

参数的属性对应的set方法实现的效果
alphasetAlpha改变透明度
translationXsetTranslationX沿X轴平移
translationYsetTranslationY沿Y轴平移
scaleXsetScaleX沿X轴缩放
scaleYsetScaleY沿Y轴缩放
rotationXsetRotationX绕X轴旋转
rotationYsetRotationY绕Y轴旋转
rotationsetRotation绕Z轴旋转

ViewPropertyAnimator

ViewPropertyAnimator只能作用于View而不能作用于其他object。假如需要同时对多个属性执行动画时,ViewPropertyAnimator效率更高,代码更简洁、更易读。

1
view.animate().x(500f).y(500f).start();

AnimationSet组合动画

AnimationSet用于组合多个动画进行复杂的动画显示,可以设定动画的先后顺序。

1
2
3
4
5
6
7
8
9
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator objectAnimatorTranslate = ObjectAnimator.ofFloat(iv, "translationX", 0f, 500f);
ObjectAnimator objectAnimatorRotateX = ObjectAnimator.ofFloat(iv, "rotationX", 0f, 360f);
ObjectAnimator objectAnimatorRotateY = ObjectAnimator.ofFloat(iv, "rotationY", 0f, 360f);
animatorSet.setDuration(1000);
animatorSet.play(objectAnimatorTranslate)
.after(objectAnimatorRotateX)
.after(objectAnimatorRotateY);
animatorSet.start();

AnimationListener

动画执行的监听,用于监听动画回调实现自定义功能。

  • onAnimationStart 动画开始

  • onAnimationRepeat 重复动画

  • onAnimationEnd 动画结束

Interpolator插值器

动画变换时如果想实现非线性效果,则可使用Interpolator插值器。所有的Interpolator都实现了Interpolator接口,这个接口定义了一个方法:float getInterpolation(float input),此方法由系统调用,input代表动画的时间,在0和1之间,也就是开始和结束之间。

系统内置有九种:

  • AccelerateDecelerateInterpolator 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速
  • AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
  • AnticipateInterpolator 开始的时候向后甩一点然后向前
  • AnticipateOvershootInterpolator 开始的时候向后甩一点然后向前超过设定值一点然后返回
  • BounceInterpolator 动画结束的时候弹起,类似小球落地
  • CycleInterpolator 动画循环播放特定的次数回到原点,速率改变沿着正弦曲线
  • DecelerateInterpolator 在动画开始的地方快然后慢
  • LinearInterpolator 以线性常量速率改变
  • OvershootInterpolator 向前超过设定值一点然后返回到原来位置

另外,插值器也可以自定义。所有的Interpolator都实现了Interpolator接口,这个接口定义了一个方法:float getInterpolation(float input),此方法由系统调用,input代表动画的时间,在0和1之间,也就是开始和结束之间。
例如:LinearInterpolator:

1
2
3
public float getInterpolation(float input) {  
return input;
}

PropertyValuesHolder

PropertyValuesHolder保存了动画过程中所需要操作的属性和对应的值。

1
2
3
4
5
6
7
8
// 将需要操作的多个属性和值封装起来,一起放到ObjectAnimator中,相当于set操作。
PropertyValuesHolder rotateHolder = PropertyValuesHolder.ofFloat("Rotation", 0, 360, 0, -360,0);
PropertyValuesHolder scaleXHolder = PropertyValuesHolder.ofFloat("scaleX", 1, 2, 1,2,1);
PropertyValuesHolder scaleYHolder = PropertyValuesHolder.ofFloat("scaleY", 1, 2, 1,2,1);
ObjectAnimator objectAnim = ObjectAnimator.ofPropertyValuesHolder(ivHolderTarget,rotateHolder, scaleXHolder, scaleYHolder);
objectAnim.setDuration(2000);
objectAnim.setInterpolator(new LinearInterpolator());
objectAnim.start();

KeyFrame

Keyframe用来保存一对时间/变量的动画值。

1
2
3
4
5
6
7
8
9
10
11
12
// fraction:代表一个动画的时间值,范围为0-1,动画从0开始,到1结束。
// value:就是在对应时间点所要设置的变量值。
Keyframe.ofFloat(float fraction, float value)

Keyframe scaleFrame1 = Keyframe.ofFloat(0f, 1.0f);
Keyframe scaleFrame2 = Keyframe.ofFloat(0.5f, 2.0f);
Keyframe scaleFrame3 = Keyframe.ofFloat(1.0f, 1.0f);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", scaleFrame1, scaleFrame2, scaleFrame3);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", scaleFrame1, scaleFrame2, scaleFrame3);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(target, scaleX, scaleY);
animator.setDuration(2000);
animator.start();

TypeEvaluator

TypeEvaluator可用于实现自定义计算动画的变化过程。

1
2
3
4
5
6
7
8
9
10
11
// 实现抛物线动画
valueAnimator.setEvaluator(new TypeEvaluator() {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
/** x方向 10px/s ,则 y方向 0.5 * 100 * t **/
PointF point = new PointF();
point.x = 10 * fraction;
point.y = 0.5f * 10 * fraction * fraction;
return point;
}
});

其他

同个动画可以多种方式实现,例如将View移动到(100f, 100f)坐标:

1、多个ObjectAnimator 组合

1
2
3
4
5
ObjectAnimator animX = ObjectAnimator.ofFloat(view, "x", 100f);
ObjectAnimator animY = ObjectAnimator.ofFloat(view, "y", 100f);
AnimatorSet animSet = new AnimatorSet();
animSet.playTogether(animX, animY);
animSet.start();

2、使用ViewPropertyAnimator

1
2
3
PropertyValuesHolder xHolder = PropertyValuesHolder.ofFloat("x", 100f);
PropertyValuesHolder yHolder = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(view, xHolder, yHolder).start();

3、使用一个ObjectAnimator + PropertyValuesHolder

1
view.animate().x(100f).y(100f).start();

0%