动画[4]PropertyAnimator ObjectAnimator

来源:互联网 发布:vb程序改错数字金字塔 编辑:程序博客网 时间:2024/05/23 15:11

【参考链接】

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 classWrapperView {
   
privateViewmTarget;

    public
WrapperView(View target){
       
this.mTarget=target;
   
}

   
public intgetWidth(){
       
returnmTarget.getLayoutParams().width;
   
}

   
public voidsetWidth(intwidth){
       
mTarget.getLayoutParams().width=width;
       
mTarget.requestLayout();//需要触发显示效果的改变
   
}
}

 

WrapperView wv=newWrapperView(tv);
ObjectAnimatoranimator = ObjectAnimator.ofInt(wv,"width",100,300);
animator.setDuration(3000);
animator.start();

 

ofPropertyValuesHolder()

如果要改变一个对象的多个属性,除了可以使用AnimatorSet,还可以使用ofPropertyValuesHolder()

ofPropertyValuesHolder()虽然ValueAnimator就已经提供了,但是其使用时需要指定target,而ValueAnimatorsetTarget()方法默认实现为空,所以ofPropertyValuesHolder()ObjectAnimator中才有效。

PropertyValuesHolderpvh1=PropertyValuesHolder.ofFloat("translationX",0,300);
PropertyValuesHolderpvh2=PropertyValuesHolder.ofFloat("translationY",0,300);
ObjectAnimatoranimator = ObjectAnimator.ofPropertyValuesHolder(tv,pvh1,pvh2);
animator.setInterpolator(newBounceInterpolator());
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);

//属性1Y坐标运动:下落

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);

 

//属性2X坐标运动:曲折

//用三个关键帧构造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(
newRunnable() {//这两个方法从API 16开始
           
@Override
           
public voidrun() {

           }
       })
       .withEndAction(
newRunnable() {
           
@Override
           
public voidrun() {

           }
       })
       .setDuration(
3000)
       .start()
;//可以不用调用start(),自动驱动

 

 

原创粉丝点击