Android 3.0之前,支持两种动画模式,Tween animation & Frame animation, 在Android 3.0 中又引入了新的动画系统:Property animation。
这三种动画模式,又被称之
View animation (Tween animation) 补间动画;
Drawable Animation(Frame animation) 帧动画;
Property Animation 属性动画。
一。View Animation (视图动画) - Tween 动画
通过修改View的绘制效果来改变view对象,view对象本身没有发生任何变化。 由于view自身没有办法操作这些属性,因此,需要该view的父view帮助其完成效果;
1. View的绘制流程:
每一个窗口就是一棵View树,绘制所需要执行的顺序如下:
1)绘制背景;
2)如有需要,保存canvas 的层为淡入或淡出做准备;
3)绘制View本身的内容,通过调用View.onDraw(canvas)实现;
4)绘制子view,通过dispatchDraw(canvas)实现;
dispatchDraw->drawChild->child.draw(canvas)
保证每一个子view的draw函数都被调用,通过这种递归调用从而让整个View树中的所有View的内容都得到绘制。
注意:在调用每个子View的draw函数之前,需要绘制的view的绘制位置是在Canvas通过translate函数调用来进行切换的,窗口中的所有View共用一个canvas。
5)如果需要,绘制淡入淡出相关的内容并恢复保存的画布所在的层layer
6) 绘制滚动条等修饰内容
当一个子View需要重画时,它会调用invalidate(),通知其父View这个子View需要重画,这个过程一直向上遍历直到ViewRoot,当ViewRoot接收到这个通知后,就会调用ViewRoot的draw函数完成绘制。
2.视图动画的绘制:通过父View不断调整子View的画布坐标系来实现的。
假设一个平移动画(100,200) -> (100, 500)
子View调用startAnimation,把一个Animation动画传给子View,并通知子View进行重画。当执行父View的dispatchDraw方法时,发现子View有平移动画,当前平移位置是(100,200), 于是父View通过调用canvas.traslate(100,200)来告诉子View在这个位置开始绘制,也就是动画的第一帧;如果父View发现子View还有动画,就会调用自己的invalidate()函数刷新自己, 就会不断的调用dispatchDraw函数,产生动画的后续帧;当再次进行dispatchDraw时,父View根据平移动画产生出第二帧的平移位置(100, 300),然后继续执行上述操作,继续产生第三帧,第四帧,直到动画播放完成。
二。Drawable Animation(Frame Animation) 帧动画
帧动画,有点像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。
如下:在xml中定义的方式
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/drawable1" android:duration="200" />
<item android:drawable="@drawable/drawable2" android:duration="200" />
<item android:drawable="@drawable/drawable3" android:duration="200" />
</animation-list>
注意:
Drawable Animation 必须以<animation-list>为根元素,以<item>表示要轮换显示的图片,duration表示持续的时间放入/res/drawable目录下即可。Demo:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView) findViewById(R.id.imageView1);
imageView.setBackgroundResource(R.drawable.drawable_anim);
anim = (AnimationDrawable) imageView.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
anim.stop();
anim.start();
return true;
}
return super.onTouchEvent(event);
}
请注意如下:
1)要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会FC;
2) 在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次;
3) 不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。
三。Property Animation 属性动画
在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。
1. 在Property Animation中,可以对动画应用以下属性:
1) Duration:动画的持续时间;
2) TimeInterpolation:属性值的计算方式,如先快后慢;
3) TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值;
4) Repeat Count and behavoir:重复次数与方式,如播放3次、5次、无限循环,也可以设置此动画一直重复,或播放完时再反向播放;
5) Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移;
6) Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影响。
2. 在属性动画里面有三个核心类:
1) ValueAnimator
ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。
应用Property Animation有两个步聚:
1.1) 计算属性值
1.2) 根据属性值执行相应的动作,如改变对象的某一属性。
2) ObjectAnimator
继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。
3) AnimatorSet
AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。
其它关键类:
4)TypeEvalutors
根据属性的开始、结束值与TimeInterpolation计算出的因子,计算出当前时间的属性值。
android提供了以下几个evalutor:
IntEvaluator:属性的值类型为int;
FloatEvaluator:属性的值类型为float;
ArgbEvaluator:属性的值类型为十六进制颜色值;
TypeEvaluator:一个接口,可以通过实现该接口自定义Evaluator。
public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
}
}
根据动画执行的时间跟应用的Interplator,会计算出一个0~1之间的因子,即evalute函数中的fraction参数.
5)TimeInterplator
Time interplator定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。
在Property Animation中是TimeInterplator,在View Animation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了TimeInterplator。Interplator继承自TimeInterplator,内部没有任何其他代码。
目前Android 提供的Interplator 有如下几种:
AccelerateInterpolator 加速,开始时慢中间加速
DecelerateInterpolator 减速,开始时快然后减速
AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速
AnticipateInterpolator 反向 ,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator 反向加回弹,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
LinearInterpolator 线性,线性均匀改变
OvershottInterpolator 回弹,最后超出目的值然后缓慢改变到目的值
TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口
参考:
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html
http://www.cnblogs.com/zxcblog/p/3259920.html
http://zhouyunan2010.iteye.com/blog/1972789