前面我们分析了Android动画中的view动画和帧动画,这篇来说说Android中的属性动画,也是Android最后的一个动画效果
属性动画
属性动画是Api11新加入的特性,和view动画不同,它是对对象进行扩展,属性动画可以对任何对象做动画效果,甚至还可以没有对象,并且动画效果得到很大的加强,不仅仅像view动画那样只能支持4种变换,属性动画种有ValueAnimator,ObjectAnimator和AnimatorSet等概念,通过他们可以实现很棒的效果,我们可以简单的把它理解为,只要对象有这个属性,它都能实现动画效果,我们先来看看一个简单的小例子:
ObjectAnimator
ObjectAnimator
.ofFloat(myView, "rotationX", 0.0F, 360.0F)
.setDuration(500)//
.start();
这段代码的意思是说,指定view的x坐标在500ms内旋转360度,我们看看ofFloat的源码:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator anim = new ObjectAnimator(target, propertyName);
anim.setFloatValues(values);
return anim;
可以看到有三个参数,第一个就是我们需要传入的对象,第二个是属性名字,第三个就是多值,我们可以看到它内部就是用ObjectAnimator 来实现的,这里注意一下,第二个属性名字如果随便写一个,轻者动画没效果,重者则崩溃,为什么呢?下篇文章会来介绍,但是如果我们需要动画有效果,那我们则需要手动调用,当我们需要一个view需要做多种动画效果的时候,我们就需要这样手动去调用,例子:
public void rotateyAnimRun(final View view)
{
ObjectAnimator anim = ObjectAnimator
.ofFloat(view, "test", 1.0F, 0.0F)
.setDuration(500);
anim.start();
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
float cVal = (Float) animation.getAnimatedValue();
view.setAlpha(cVal);
view.setScaleX(cVal);
view.setScaleY(cVal);
}
});
}
也可以这样写,通过一个属性的holder分别设置view要做的动画效果,然后再添加到ObjectAnimator来实现,这样更简单易懂:
public void propertyValuesHolder(View view)
{
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
0f, 1f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,
0, 1f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,
0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();
}
ValueAnimator
ValueAnimator跟ObjectAnimator差不多,来看看一个小例子:
ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight
- myView.getHeight());
animator.setTarget(myView);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
}
});
我们发现,它跟ObjectAnimator的差别是在于它没有设定属性名称这个参数,这样的好处在于我们可以让多个属性做这个动画效果,而不是指定某一个属性去做,灵活性更高,上面代码的意思是让我们的view在1000ms内做自由落体运动,一开始我们让view处于一个静止状态,然后不断的用屏幕的高度减去view的高度,在y坐标上做平移效果,随着高度的减少,view就自由落下
AnimatorSet
最后来说说动画集合:
AnimatorSet animatorSet =new AnimatorSet();
//同时执行
animatorSet.playTogether(
ObjectAnimator.ofFloat(myView,"rotationX",0,360),
ObjectAnimator.ofFloat(myView,"rotationY",0,180),
ObjectAnimator.ofFloat(myView,"translationX",0,90),
ObjectAnimator.ofFloat(myView,"translationY",0,90),
ObjectAnimator.ofFloat(myView,"scaleX",1,1.5f),
ObjectAnimator.ofFloat(myView,"scaleY",1,0.5f)
);
animatorSet.setDuration(1000).start();
很简单,就是将各种动画放到AnimatorSet 中,然后让他们同时执行,就可以了,假如说我们需要让动画2跟在动画1后面,动画3跟着动画2后面,依次执行,那么,我们可以这样写:
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim2).after(anim1);
animSet.play(anim3).after(anim2);
animSet.setDuration(1000);
animSet.start();
如果我们需要让动画1,动画2同时执行,动画3跟在动画2(或者动画1)后面,我们可以这样写:
AnimatorSet animSet = new AnimatorSet();
animSet.play(anim1).with(anim2);
animSet.play(anim3).after(anim2);
animSet.setDuration(1000);
animSet.start();
好了,关于属性动画就到这了