在Android 3.0之前,系统提供的动画有帧动画和补间动画,帧动画的原理就是将一些图片连续的播放出来,补间动画是对View进行操作包括AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation这四种动画方式。由于它们有一些局限性,比如:1、不具有交互性,当View执行完动画后,其响应事件依然停留在动画执行前的地方;2、只能在View上起作用,它的执行对象必须要是一个具体的View。
在Android 3.0,系统引入属性动画,属性动画不仅可以实现之前动画的功能,主要的特点是可以控制一个对象或者对象的属性值,达到动画效果。
ValueAnimator
ValueAnimation是属性动画中一个比较核心的类,它的实现原理是不断改变属性值,上层通过这个值来刷新执行动画效果。下面看一下用法:
/**
* 代码实现ValueAnimator
*/
private void codeValueAnimator() {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 10.0f);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.i(TAG, "currentValue = " + currentValue);
}
});
valueAnimator.start();
}
我们可以从onAnimationUpdate回调中拿到变化的值,然后就可以执行我们想要动画操作了。当然也可以用XML的方式,在res目录下面新建animator文件夹,所有属性动画都放在这个文件夹下面,一共有三种标签:
ValueAnimator用xml方式实现和引用:
/**
* XML实现ValueAnimator
*/
private void xmlValueAnimator() {
Animator animator = AnimatorInflater.loadAnimator(MainActivity.this, R.animator.value_anim_file);
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.i(TAG, "[onAnimationStart]");
}
@Override
public void onAnimationEnd(Animator animation) {
Log.i(TAG, "[onAnimationEnd]");
}
@Override
public void onAnimationCancel(Animator animation) {
Log.i(TAG, "[onAnimationCancel]");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.i(TAG, "[onAnimationRepeat]");
}
});
animator.start();
}
ObjectAnimator
ObjectAnimator继承ValueAnimator,所以的本质和ValueAnimator是一样的,都是通过修改属性值达到改变动画的效果。现在具体看一下ObjectAnimator的用法
/**
* 代码实现水平移动
*/
private void codeTranslationX() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mBtnCodeTranslationX, "translationX", 200, 0);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
调用ObjectAnimator的ofFloat方法,第一个参数表示操作的对象,第二个参数表示要操作的属性,上面是水平移动,这个属性在View中对应的是setTranslationX()方法,其他的还有“alpha”、“scaleX”、“rotation”,在View中都可以找到对应的set和get方法,如果没有的话就自己定义,然后实现set和get方法的逻辑了,当然就需要调用ObjectAnimator的ofObject方法了。后面的参数代表动画的初始值和结束值,它是一个可变的参数。最后设置动画的执行时间,再调用start方法就可以了。
AnimatorSet
如果想要多个动画一起或者前后顺序执行,我们可以使用AnimatorSet,主要方法有:
/**
* 代码实现组合动画
*/
private void codeAnimatorSet() {
AnimatorSet set = new AnimatorSet();
Animator a1 = ObjectAnimator.ofFloat(mBtnCodeAnimatorSet, "alpha", 1, 0, 1);
Animator a2 = ObjectAnimator.ofFloat(mBtnCodeAnimatorSet, "scaleX", 0, 1);
set.play(a1).after(a2);
set.setDuration(3000);
set.start();
}
上面代码先执行缩放操作,再改变透明度。
ViewPropertyAnimator
ViewPropertyAnimator跟ObjectAnimator功能类似,只不过代码实现的方式更加面向对象,比如我要让View水平移动,用ObjectAnimator的写法是:
/**
* 代码实现水平移动
*/
private void codeTranslationX() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mBtnCodeTranslationX, "translationX", 200, 0);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
用ViewPropertyAnimator写法:
/**
* ViewPropertyAnimator
*/
private void viewProperty() {
mBtnViewProperty.animate().translationX(200);
}
上面mBtnViewProperty.animate()可以获取到ViewPropertyAnimator的实例对象,然后就可以调用它的方法了。
最后还有一些关于属性动画比较高级的东西,比如自定义TypeEvaluator,它的作用是控制动画变化的那个值,例如:ObjectAnimator.ofFloat()方法里面就实现了一个FloatEvaluator它实现了TypeEvaluator接口,并重写了evaluate方法,自定义TypeEvaluator主要用在自定义动画属性上,即ObjectAnimator.ofObject()方法。
还有一个是TimeInterpolator,它可以控制动画的运动速率,比如加速运动、减速运动,对应的是AccalerateInterpolator、DecelerateInterpolator,他们都是TimeInterpolator的子类。当然我们也可以自定义实现。
Demo下载