前面一文讲解了Android属性动画之ValueAnimator使用,我们知道ValueAnimator可以对数值进行动态变化,或者对对象进行变化,这里继续来了解一下ValueAnimator的子类ObjectAnimator。
推荐博客:http://blog.csdn.net/guolin_blog/article/details/43536355
ObjectAnimator相对其父类,功能更加强大了,可以对一个对象的属性进行动画操作。比如说View的alpha属性。
下面就看一下ObjectAnimator的一些用法:
ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"alpha",1f,0f,1f);
animator.setDuration(4000);
animator.start();
可以看到,我们还是调用了ofFloat()方法来去创建一个ObjectAnimator的实例,只不过ofFloat()方法当中接收的参数有点变化了。这里第一个参数要求传入一个object对象,我们想要对哪个对象进行动画操作就传入什么,这里我传入了一个textview。第二个参数是想要对该对象的哪个属性进行动画操作,由于我们想要改变TextView的透明度,因此这里传入"alpha"。后面的参数就是不固定长度了,想要完成什么样的动画就传入什么值,这里传入的值就表示将TextView从常规变换成全透明,再从全透明变换成常规。之后调用setDuration()方法来设置动画的时长,然后调用start()方法启动动画,看一下动画效果:
这里我们需要考虑第二个参数属性到底该传什么值,为什么我们传入“alpha”,ObjectAnimator就会去改变textView的透明度呢?
传入的属性与传入的对象是关联的。ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法,如果这个对象都没有这个属性对应的get和set方法,那么是看不到对象的显示效果有变化,但是传入的值还是会变化的。
我们可以来看测试一下:
ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"xxx",1f,0f,1f);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
Log.d("Test", "cuurent value is " + value);
}
});
animator.start();
点击没有任何效果
看log:
D/Test: cuurent value is 1.0
D/Test: cuurent value is 1.0
D/Test: cuurent value is 0.9985742
D/Test: cuurent value is 0.9943008
D/Test: cuurent value is 0.98768836
D/Test: cuurent value is 0.9779293
D/Test: cuurent value is 0.9653816
D/Test: cuurent value is 0.9510565
D/Test: cuurent value is 0.93320465
D/Test: cuurent value is 0.91269153
D/Test: cuurent value is 0.8910065
D/Test: cuurent value is 0.8655012
D/Test: cuurent value is 0.837528
D/Test: cuurent value is 0.8090169
D/Test: cuurent value is 0.7764865
D/Test: cuurent value is 0.74174184
D/Test: cuurent value is 0.70710677
D/Test: cuurent value is 0.6683521
D/Test: cuurent value is 0.62769127
D/Test: cuurent value is 0.58778536
D/Test: cuurent value is 0.5437604
D/Test: cuurent value is 0.49818516
D/Test: cuurent value is 0.45399046
D/Test: cuurent value is 0.40577984
D/Test: cuurent value is 0.3564117
D/Test: cuurent value is 0.30901706
D/Test: cuurent value is 0.25780725
D/Test: cuurent value is 0.20586258
D/Test: cuurent value is 0.1564343
D/Test: cuurent value is 0.103486896
D/Test: cuurent value is 0.05024445
D/Test: cuurent value is 0.0
D/Test: cuurent value is 0.053381562
D/Test: cuurent value is 0.106610894
D/Test: cuurent value is 0.1564343
D/Test: cuurent value is 0.20893562
D/Test: cuurent value is 0.2608415
D/Test: cuurent value is 0.30901706
D/Test: cuurent value is 0.35934532
D/Test: cuurent value is 0.4086492
D/Test: cuurent value is 0.45399046
D/Test: cuurent value is 0.5009067
D/Test: cuurent value is 0.54639435
D/Test: cuurent value is 0.58778536
D/Test: cuurent value is 0.63013387
D/Test: cuurent value is 0.6706855
D/Test: cuurent value is 0.7071068
D/Test: cuurent value is 0.743845
D/Test: cuurent value is 0.7784622
D/Test: cuurent value is 0.80901694
D/Test: cuurent value is 0.8392403
D/Test: cuurent value is 0.8670707
D/Test: cuurent value is 0.89100647
D/Test: cuurent value is 0.91397095
D/Test: cuurent value is 0.93432903
D/Test: cuurent value is 0.9510565
D/Test: cuurent value is 0.9661963
D/Test: cuurent value is 0.97858095
D/Test: cuurent value is 0.9876883
D/Test: cuurent value is 0.9946308
D/Test: cuurent value is 0.998737
D/Test: cuurent value is 1.0
那么TextView 是不是有"alpha"对应的get和set方法呢?,这个我们可以查找一下:
在View类中这两个方法,TextView 是View子类,所以肯定没问题的。
public float getAlpha()
public void setAlpha(float alpha)
同样我们可以在View中找到以下这些方法:
public float getRotation()//旋转
public void setRotation(float rotation)
public float getTranslationX()//x方向平移
public void setTranslationX(float translationX)
public float getTranslationY()//y方向平移
public void setTranslationY(float translationY)
public float getScaleX()//x方向缩放
public void setScaleX(float scaleX)
public float getScaleY()//y方向缩放
public void setScaleY(float scaleY)
所以我们在View的子类进行操作时,可以传入这些属性名:rotation,translationX,scaleY......
关于操作这些属性的代码片段就没贴了。
ObjectAnimator大部分情况我们用来改变View的属性值产生动画效果。
和Animation动画一样,属性动画也可以同时进行多个动画,用AnimatorSet来实现
float x1 = textView.getTranslationX();
ObjectAnimator animator = ObjectAnimator.ofFloat(textView,"alpha",1f,0f,1f);
ObjectAnimator animator11 = ObjectAnimator.ofFloat(textView,"rotation",0f,360f);
ObjectAnimator animator22 = ObjectAnimator.ofFloat(textView,"translationX",x1,x1+200f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(animator11).with(animator).with(animator22);
animatorSet.setDuration(4000);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
animatorSet.start();
上面三个动画效果:透明度变化,旋转,x方向平移。
AnimatorSet这个类,有一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
另外可以设置动画的监听器,在动画整个过程中,做些事情:
ValueAnimator.AnimatorUpdateListener
这个监听的回调方法
onAnimationUpdate(ValueAnimator animation)//可以获取实时变化的中间值
Animator.AnimatorListener
这个监听有以下几个回调
onAnimationCancel(Animator animation)//动画取消
onAnimationEnd(Animator animation)//动画结束
onAnimationRepeat(Animator animation)//动画重复开始
onAnimationStart(Animator animation)//动画开始
Animator.AnimatorPauseListener
这个监听有以下几个回调
onAnimationPause(Animator animation)//动画暂停
onAnimationResume(Animator animation)//动画继续
在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:
那么比如说我们想要实现一个透明度值从0到1过渡的动画,在XML当中就可以这样写:
然后在代码中使用:
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.object_animator);
animator.setTarget(textView);
animator.start();