在Android3.0之后,Google推出了属性动画的框架来帮助开发者实现更加丰富的动画效果。而在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator的配合。使用ObjectAnimator进行精细化的控制,只控制一个对象的属性值,而使用多个ObjectAnimator组合到AnimatorSet形成一个动画,属性动画通过调用属性的get,set方法来真实的控制一个view的属性值。
1.ObjectAnimator
ObjectAnimator是属性动画中最重要的类,创建一个ObjectAnimator对象只需要调用它的静态工厂类即可。参数包括一个对象和对象的属性的名字,但是这个属性必须是有get和set方法的属性。内部通过java的反射机制来调用set函数来修改属性的值。同样也可以调用setInterpolator设置相应的差值器。
在前我们曾说过,视图动画并不能改变事件响应的位置,它只是单纯的修改了显示。如果使用旧的视图动画产生上面的效果,那么按钮的时机点击效果依然在原来的地方,点击移动后的地方是不会有点击事件发生的。而属性动画却不是一个样的,由于它改变了一个view的属性,所以事件响应的区域额同样发生了变化。这时候点击移动后的按钮,就会响应点击事件。
代码如下:
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "rotationX", 0, 360);
objectAnimator.setDuration(1000);
objectAnimator.start();
view.getTranslationX()和 view.getTranslationY();这两个属性是控制viiew兑现从布局容器的左上角坐标开始的位置的;
view.getRotationX();view.getRotation(); view.getRotationY()这三个属性是控制view围绕支点进行2D和3D旋转的;
view.getScaleY();和view.getScaleX()这两个属性控制view对象围绕他的支点进行2D缩放的;
view.getPivotX()和view.getPivotY()控制view对象的支点的位置,围绕这个支点进行旋转和缩放变换处理。默认情况下,该支点的未知子就是view对象的中心点。
x和y,它描述的是view对象在他的容器中的最终的位置,它是最初的左上角坐标和translationX,translationY值的累积和;
alpha:表示的是view对象的alpha透明度,默认值是1(不透明),0代表的是完全透明;
2.PropertyValuesHolder
类似视图动画中的AnimationSet,在属性动画中,如果针对同一个对象的多个属性,要同时作用多种动画,可以使用PropertyValuesHolder来实现。比如举例的旋转动画,在旋转的时候要同时你改变X.Y轴的缩放,可以这样的实现:
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("rotationX", 0, 360);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f,0, 1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleX", 1f,0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000).start();
在代码中,分别使用PropertyValuesHolder对象来控制rotationX,scaleY,scaleX这三个属性,最后调用ObjectAnimator.ofPropertyValuesHolder方法实现多属性动画的共同作用,整个实现方法非常类似AnimatonSet的使用。
3.ValuesAnimator
ValuesAnimator在属性动画中占有非常重要的地位,ObjectAnimator也是继承自ValuesAnimator.
ValuesAnimator本身并不提供任何动画效果,他是用来产生一定规律的的数字,从而让调动者来控制动画的实现过程,ValuesAnimator的一般使用方法如下所示,通常情况下,在ValuesAnimator的AnimatorUpdataListener中监听数值的变换,从而完成动画的实现。
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100);
valueAnimator.setTarget(view);
valueAnimator.setDuration(1000).start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Float values = (Float) animation.getAnimatedValue();
// TODO: 2016/8/7 use value
}
});
4.动画事件的监听
一个完整的动画具有start,repeat,end,cancel四个过程,通过android提供的借口也已很方便的监听这四个事件;
ObjectAnimator ob = ObjectAnimator.ofFloat(view, "alpha",0.5f);
ob.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
当然大部分时候我们只关心animatiorEnd事件,在动画结束的时候要干点什么。
5.AnimatorSet
针对一个属性同时作用多个属性动画效果,前面已经用PropertyValuesHolder实现了这样的效果,而AniamtorSet不仅能实现这样的效果,同时还能实现更精确的控制,同样实现PropertyValuesHolder演示的动画效果,如果使用AniamtorSet来实现,又该怎么做呢??
ObjectAnimator ani1 = ObjectAnimator.ofFloat(view, "rotateX",0, 360);
ObjectAnimator ani2 = ObjectAnimator.ofFloat(view, "scaleX",1f,0, 1f);
ObjectAnimator ani3 = ObjectAnimator.ofFloat(view, "scaleY",1f,0, 1f);
AnimatorSet set1 = new AnimatorSet();
set1.setDuration(1000);
set1.playTogether(ani1, ani2, ani3);
set1.start();
在属性动画中,AnimatorSet 是通过palyTogether(),palySuquentially(),animSet.play().with(),defore(),after()这些方法来控制多个动画的协同工作方式,从而做到对动画播放顺序的精确控制。
6.在XML中使用属性动画
属性动画同视图动画一样,也可以直接写在XML文件中,代码如下:
在程序中使用的XML定义的属性动画也非常简单,代码如下:
public void scaleX(View view)
{
Animator anim = AnimatorInflater.loadAnimator(this,R.Animator.scaleX);
anim.setTaget(view);
anim.start();
}