在Property Animation中,你可以对动画应用以下属性:
Duration:动画的持续时间
Time interpolation:应用动画的属性的属性值如何改变,即根据动画的进行时间其属性值的计算方式
Repeat Country and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最中刷新间隔还受系统繁忙程序与硬件的影响
Property Animation的工作方式
对于下图的动画,这个对象的X坐标在40ms内从0移动到40 pixel.按默认的10ms刷新一次,这个对象会移动4次,每次移动40/4=10pixel。
也可以改变属性值的改变方法,即设置不同的interpolation,在下图中运动速度先逐渐增大再逐渐减小
下图显示了与上述动画相关的关键对象
ValueAnimator包含的应用动画的属性的开始值,结束值,持续时间的属性。
ValueAnimator还封装了一个TimeInterpolator,TimeInterpolator定义了属性值在开始值与结束值之间的插值方法。
ValueAnimator还封装了一个TypeAnimator,也跟属性值的计算有关。
ValueAnimator根据动画已进行的时间跟总时间的比计算出一个时间因子(0~1),然后根据TimeInterpolator出另一个因子,最后TypeAnimator通过这个因子计算出属性值,如上例中10ms时:
在时间因子a=10ms/40ms=0.25
经相应的插值方法后(inteplator)的插值因子:大约为0.15(计算公式为:(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; input即为时间因子)
最后计算出在10ms时的属性值:0.15*(40-0)=6pixel。
ValueAnimation
包含中Property Animation动画的所有核心功能,如动画时间,开始结束属性值,相应时间属性值计算方法等。就用Property Animation有两步,一、计算属性值;二、将属性值应用于对象。ValuAnimiation只完成了第一步,如果要完成第二步,需要 Animator.AnimatorListener接口。
ObjectAnimator
ValueAnimator的子类,要指定一个对象及该对象的一个属性,当属性值计算完成时自动应用于该对象的相应属性,即完成了Property Animation的两步。一般都会用ObjectAnimator,但其有一定限制,如需要应用玩的对象有accessor方法(如 setColor)。
AnimatorSet
提供了一个把多个动画组合成一个组的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
Evalutors
根据Animator中的start time,end time,duration等计算属性值,android提供了以下几个evalutor:
IntEvalutor:属性值为int;
FloatEvalutor:属性值为float;
ArgbEvalutor:属性值为十六进制颜色值;
TypeEvalutor:一个接口,你可以通过实现该接口自定义Evalutor。
自定义TypeEvalutor很简单,只需要实现一个方法,如FloatEvalutor的定义:
1 | public class FloatEvaluator implements TypeEvaluator { |
2 | public Object evaluate(float fraction, Object startValue, Object endValue) { |
3 | float startFloat = ((Number) startValue).floatValue(); |
4 | return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); |
5 | } |
6 | } |
根据动画执行的时间跟应用的Interplator,会计算出一个0~1之间的因子,即evalute函数中的fraction参数,通过上述FloatEvaluator应该很好看出其意思。
Time Interplator
time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。
AccelerateInterpolator | 开始时慢,中间加速 |
DecelerateInterpolator | 开始时快然后减速 |
AccelerateDecelerateInterolator | 开始结束时慢,中间加速 |
AnticipateInterpolator | 先向相反方向改变一段再加速播放 |
AnticipateOvershootInterpolator | 先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值 |
BounceInterpolator | 快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100 |
CycleIinterpolator | 值在[-2*from-to,to]这间循环指定次数 |
LinearInterpolator | 线性均匀改变 |
OvershottInterpolator | 最后超出目的值然后缓慢改变到目的值 |
TimeInterpolator | 一个接口,允许你自定义interpolator |
ValueAnimator用法
01 | ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); |
02 | animation.setDuration(1000); |
03 | animation.addUpdateListener(new AnimatorUpdateListener() { |
04 | @Override |
05 | public void onAnimationUpdate(ValueAnimator animation) { |
06 | Log.i("update", ((Float)animation.getAnimatedValue()).toString()); |
07 | } |
08 | }); |
09 | animation.setInterpolator(new CycleInterpolator(3)); |
10 | animation.start(); |
ObjectAnimator用法
01 | tv=(TextView)findViewById(R.id.textview1); |
02 | btn=(Button)findViewById(R.id.button1); |
03 | btn.setOnClickListener(new OnClickListener() { |
04 | @Override |
05 | public void onClick(View v) { |
06 | ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f); |
07 | oa.setDuration(3000); |
08 | oa.start(); |
09 | } |
10 | }); |
要想使用ObjectAnimator,应该满足以下条件:
想通过ObjectAnimator应用动画的属性就能有一个setter函数:set<PropertyName>(双峰命名法)
在上面的例子只像ofFloat类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数你只设置了一个的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:get<PropertyName>
如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。
如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。
根据应用动画的对象或属性的不同,可能需要在onAnimationUpdate函数中调用invalidate()函数刷新视图。
通过AnimationSet应用多个动画
以下例子同时应用5个动画:
播放anim1;
同时播放anim2,anim3,anim4;
播放anim5。
1 | AnimatorSet bouncer = new AnimatorSet(); |
2 | bouncer.play(anim1).before(anim2); |
3 | bouncer.play(anim2).with(anim3); |
4 | bouncer.play(anim2).with(anim4) |
5 | bouncer.play(anim5).after(amin2); |
6 | animatorSet.start(); |
Animator.AnimatorListener
onAnimationStart()
onAnimationEnd()
onAnimationRepeat()
onAnimationCancel
ValueAnimator.AnimatorUpdateListener
onAnimationUpdate():通过监听这个事件在属性的值更新时执行相应的操作,对于ValueAnimator要监听此事件执行相应的动作,否则Animation无意义,在ObjectAnimator(继承自 ValueAnimator)中会自动更新属性,如无必要不必监听。在函数中会传递一个ValueAnimator参数,通过此参数的 getAnimatedValue()取得当前动画属性值。
可以继承AnimatorListenerAdapter而不是实现AnimatorListener接口来简化操作,这个类对AnimatorListener中的函数都定义了一个空函数体,这样我们就只用定义想监听的事件而不用实现每个函数却只定义一空函数体。
1 | ObjectAnimator oa=ObjectAnimator.ofFloat(tv, "alpha", 0f, 1f); |
2 | oa.setDuration(3000); |
3 | oa.addListener(new AnimatorListenerAdapter(){ |
4 | public void on AnimationEnd(Animator animation){ |
5 | Log.i("Animation","end"); |
6 | } |
7 | }); |
8 | oa.start(); |