Android 动画之属性动画(二)#
在这篇文章中将会通过介绍属性动画的具体使用
Animating with ValueAnimator##
首先需要获得一个ValueAnimator对象,它的获取方法是通过调用它的Factory Method: ofInt(int... values) , ofFloat(float... values) 和 ofObject(TypeEvaluator evaluator, Object... values) (int... values 表示传入的参数个数是任意的)
更多关于 ValueAnimator 的方法请查看文档:
https://developer.android.com/reference/android/animation/ValueAnimator.html
ValueAnimator mValueAnimator = ValueAnimtor.ofInt(0,10);
//ValueAnimator mValueAnimator = ValueAnimtor.ofInt(0,10,8,20);
这样的意思是说从0过渡到10,然后在过渡到8,再过渡到20
mValueAnimator.setDuration(200);
mValueAnimator.setInterpolator(new LinearInterpolator());//设置均匀计算数值
mValueAnimator.start();//通过start()来开始动画
在上面的代码中,在start()方法启动后,ValueAnimator就会在200ms内,均匀地计算出0到10的int值,我们通过监听器来获取这些值,看看是否如上所描述的一样
D/TAG: current value is 0
D/TAG: current value is 2
D/TAG: current value is 3
D/TAG: current value is 4
D/TAG: current value is 5
D/TAG: current value is 5
D/TAG: current value is 6
D/TAG: current value is 7
D/TAG: current value is 8
D/TAG: current value is 9
D/TAG: current value is 10
可以看到基本是均匀增加的,出现误差的原因之前已经讲过,理论上来是每10ms更新一次,但是具体是取决于手机本身所能提供的计时器,因此这里我们看到的是接近每20ms更新一次,而且系统本身计时存在误差,因此也就出现了误差
如果你想要进行动画的既不是整数值也不是浮点数值,那么就要用到 ofObject(TypeEvaluator evaluator, Object... values) ,比如说
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();
其中MyTypeEvaluator就是你自己定义的一个类型 ValueAnimator 只是为需要动画的属性提供一组平滑过渡的值,所以之后要需要为动画设置 监听 来得到这些值,然后在对具体的属性/对象利用这些值进行操作,有关 监听 的内容将在后面提到
Animating with ObjectAnimator
通常情况下我们用到更多的是 ObjectAnimator ,因为它可以直接指定你要进行动画的属性/对象。它的初始化方法和 ValueAnimator 的类似,不过它的方法中多了两个参数:ofFloat(Object target, String propertyName, float... values) ,第一个参数为你要进行动画的对象,第二参数为你要进行动画的属性值,比如说对象是一个TextView,你需要改变TextView的透明度这个属性.
ObjectAnimator anim = ObjectAnimator.ofFloat(mTextView, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();
更多关于 ObjectAnimator 的方法请查看文档
https://developer.android.com/reference/android/animation/ObjectAnimator.html
要非常注意的一点是, ObjectAnimator 自动修改alpha其实是调用了TextView里面 setAlpha() 这个方法!因此,要对某一属性进行动画,那么目标对象一定要有 set< propertyName >() 这个方法
我们来一起验证一下是否是这样:
(1). 先来创建一个自定义的View,命名为myView,继承自TextView
(2). 对它的透明度属性进行动画操作,一开始先不重写 setAlpha() 这个方法,来看看效果
ObjectAnimator anim = ObjectAnimator.ofFloat(myview,"alpha",0f,1f);
anim.setDuration(1000);
anim.start();
----------
@Override
public void setAlpha(float alpha) {
super.setAlpha(alpha);
}
(3). 然后我们重写 setAlpha() 这个方法,让他变成位移,看看效果
@Override
public void setAlpha(float alpha){
super.setTranslationX(alpha*200);
}
可以看出,确实是调用了 myView 里面的setAlpha()方法
假如你想要改变的属性没有对应的set方法,官方给出了这三种解决方法:
- 假如你有修改这个对象的权限,那么你可以为这个对象添加setter方法
- 使用一个你有权限去修改的 wrapper 类然后让这个 wrapper 类利用一个有效的setter方法来接收value,然后传递给对象
- 用 ValueAnimator 来替代
Choreographing Multiple Animations with AnimatorSet
很多情况下你不仅需要一个动画来满足你的需求,所以,你会要用到利用 AnimatorSet 类。它可以吧几个动画捆绑在一起,这样就可以控制这些动画是同时进行还是有序进行或者其他的。 AnimatorSet 可以互相嵌套。
把 Animator 加到 AnimatorSet 里面有两种方法:
(1). 利用 playTogether() 和 playSequentially() ,一次处理完所有 Animator
//假设前面已经创建了若干ValueAnimator/ObjectAnimator
anim1,anim2,anim3
//实例化一个AnimatorSet
AnimatorSet aniset = new AnimatorSet();
//调用 playTogether (Animator... items)
aniset.playTogether(anim1,anim2,anim3);
//你可以把这三个动画编成一个集合再调用
playTogether(Collection<Animator> items),这里就不再演示
(2). 利用 Builder 里面的 play(),after(),before(),with() 方法来逐个添加动画,参数都是 Animator
AnimatorSet s = new AnimatorSet();
s.play(anim1).with(anim2);
s.play(anim2).before(anim3);
s.play(anim4).after(anim3);
需要注意的是,AnimatorSet 最先使用的一定是 play() 因为只有 play() 的参数才是所有它紧接着的那个动画的主语,比如上面代码的第3行,before表示在之前发生,anim2 是主语,所以意思是 before(anim3) 的主语是 anim2 ,anim2 将会在 anim3 发生前发生。再比如:
AnimatorSet s = new AnimatorSet();
s.play(anim1).before(anim2).before(anim3);
这里无论是 before(anim2) 还是 before(anim3) 都是对于 anim1 来说的,所以在 anim1 结束后, anim2 和 anim3 会同时开始。
更多关于 AnimatorSet 的方法请查看文档
https://developer.android.com/reference/android/animation/AnimatorSet.html#AnimatorSet()