【参考链接】
AndroidAnimation学习http://www.cnblogs.com/mengdd/p/3305698.html
ObjectAnimator继承自ValueAnimator,所以ValueAnimator中的方法ObjectAnimator也都可以使用。
ObjectAnimator内部其实是通过反射来调用方法来修改对象的属性,所以该类需要有此属性的get()、set()方法。
当作用于View,改变属性能够改变显示效果时,就会产生动画。
of()
通过java创建ObjectAnimator对象时,依然是使用of(),并且可以在创建时指定要改变的对象及其属性
//可以只传递一个参数,此时会从当前位置移动到指定位置//这样再次动画时会看不到效果
//传递多个参数时先移动到第一个参数
//并且此处必须为ofFloat(),因为setTranslation()的原型为setTranslationX(float translationX)
ObjectAnimatoranimator = ObjectAnimator.ofFloat(tv, "translationY", 100, 300);
animator.setDuration(3000);
animator.start();
通过xml创建ObjectAnimator对象时,可以在xml中通过propertyName指定要改变的属性,后面通过setTarget()指定要改变的对象
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationX"
android:valueType="floatType"
android:valueTo="300"
android:duration="3000">
</objectAnimator>
Animator animator1= AnimatorInflater.loadAnimator(this, R.animator.anim_test);
animator1.setTarget(tv);
animator1.start();
如果一个属性没有set()\get()方法,我们可以通过自定义一个包装类,来为这个属性增加set()\get()方法,如下所示
public class WrapperView {
private View mTarget;
public WrapperView(View target){
this.mTarget=target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width=width;
mTarget.requestLayout();//需要触发显示效果的改变
}
}
WrapperView wv=new WrapperView(tv);
ObjectAnimatoranimator = ObjectAnimator.ofInt(wv, "width", 100, 300);
animator.setDuration(3000);
animator.start();
ofPropertyValuesHolder()
如果要改变一个对象的多个属性,除了可以使用AnimatorSet,还可以使用ofPropertyValuesHolder()。
ofPropertyValuesHolder()虽然ValueAnimator就已经提供了,但是其使用时需要指定target,而ValueAnimator的setTarget()方法默认实现为空,所以ofPropertyValuesHolder()在ObjectAnimator中才有效。
PropertyValuesHolderpvh1=PropertyValuesHolder.ofFloat("translationX", 0, 300);
PropertyValuesHolderpvh2=PropertyValuesHolder.ofFloat("translationY", 0, 300);
ObjectAnimatoranimator = ObjectAnimator.ofPropertyValuesHolder(tv, pvh1, pvh2);
animator.setInterpolator(new BounceInterpolator());
animator.setDuration(3000);
animator.start();
区别在于
ofPropertyValuesHolder()需要使用ObjectAnimator的同一个Interpolator,而AnimatorSet中的ObjectAnimator可以使用各自的Interpolator。
PropertyValuesHolder的工厂方法里面,除了整形ofInt()、浮点型ofFloat()、Object类型ofObject()之外,还有一种:ofKeyframe()。
Keyframe类型对象由一个time/value对组成,定义了指定时间点的指定值。Keyframe 对象的构造也用是工厂方法:ofInt(), ofFloat(), orofObject()。Keyframe对象构造完之后就可以用ofKeyframe()工厂方法来构造PropertyValuesHolder对象。
//============================================================
// 第四个小球:利用关键帧实现曲线运动
ball = balls.get(3);
// 属性1:Y坐标运动:下落
pvhY =PropertyValuesHolder.ofFloat("y", ball.getY(),getHeight() -BALL_SIZE);
float ballX = ball.getX();
// 三个关键帧
Keyframe kf0 = Keyframe.ofFloat(0f,ballX);
Keyframe kf1 = Keyframe.ofFloat(.5f, ballX+ 100f);
Keyframe kf2 = Keyframe.ofFloat(1f, ballX+ 50f);
// 属性2:X坐标运动:曲折
// 用三个关键帧构造PropertyValuesHolder对象
PropertyValuesHolder pvhX =PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2);
// 再用两个PropertyValuesHolder对象构造一个ObjectAnimator对象
ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball,pvhY, pvhX).setDuration(DURATION / 2);
yxBouncer.setRepeatCount(1);
yxBouncer.setRepeatMode(ValueAnimator.REVERSE);
animate()
上面也说了,ObjectAnimator主要是来修改对象属性的
只不过当修改View对象的属性能够改变显示效果时,会产生动画。
对于修改View属性这种情况,为了使用起来方便,Android也直接提供了animate()方法(从API 12开始)。这个方法会返回一个ViewPropertyAnimator对象,可以在后面直接叠加方法。
tv.animate()
.alpha(0)
.y(300)
.withStartAction(new Runnable() {//这两个方法从API 16开始
@Override
public void run() {
}
})
.withEndAction(new Runnable() {
@Override
public void run() {
}
})
.setDuration(3000)
.start();//可以不用调用start(),自动驱动