Android主要提供了3类动画,第一类是Tween动画(也称为补间动画),就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。第二类就是 Frame动画,即顺序的播放事先做好的图像。第三类是属性动画,这种动画会改变对象的实际属性。
1. Tween动画(补间动画)
补间动画是一种通过指定View对象开始和结束的状态,然后通过系统自动生成需要显示的过渡效果的动画。
主要类:
Animation 动画
AlphaAnimation 渐变透明度
RotateAnimation 画面旋转
ScaleAnimation 渐变尺寸缩放
TranslateAnimation 位置移动
AnimationSet 动画集,让多个动画同时生效。
AnimationUtils 工具类,通过该类来加载xml实现的动画。
(1) AlphaAnimation
代码方式:
Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f); // 从0.1f变化到1.0f View.startAnimation(alphaAnimation );
xml实现: alpha_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="2000" /> </set>
alphaAnimation= AnimationUtils.loadAnimation(getContext(), R.anim.alpha_anim);
(2) RotateAnimation
代码实现:
Animation rotateAnimation = new RotateAnimation(0f, 360f); // 0是动画起始时的角度,360f位动画结束时的角度 rotateAnimation.setDuration(1000); this.startAnimation(scaleAnimation);
xml实现: rotate_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" <!--为动画相对于物件的X、Y坐标的开始位置, 50%表示物件的中点位置 --> android:pivotY="50%" android:duration="500" /> </set>
rotateAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.rotate_anim);
(3) ScaleAnimation
代码实现:
//初始化 Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f); // 前面两个参数表示动画起始、结束时X方向的伸缩尺寸,后面两个参数表示动画起始、结束时Y方向的伸缩尺寸。 //设置动画时间 scaleAnimation.setDuration(500); this.startAnimation(scaleAnimation);
xml实现: scanle_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="500" /> </set>
scaleAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.scanle_anim);
(4) TranslateAnimation
代码实现:
Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); // 四个参数(x1, x2, y1, y2),表示X方向从x1移动到x2, Y方向从y1移到y2. translateAnimation.setDuration(1000); //设置动画时间 this.startAnimation(translateAnimation);
xml实现: translate_anim.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="10" android:toXDelta="100" android:fromYDelta="10" android:toYDelta="100" /> </set>
translateAnimation= AnimationUtils.loadAnimation(getContext(), R.anim.translate_anim);
(5) 使用AnimationSet, 让多个动画同时生效,如:
//初始化 Translate动画 translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f); //初始化 Alpha动画 alphaAnimation = new AlphaAnimation(0.1f, 1.0f); //动画集 AnimationSet set = new AnimationSet(true); set.addAnimation(translateAnimation); set.addAnimation(alphaAnimation); //设置动画时间 (作用到每个动画) set.setDuration(1000); this.startAnimation(set);
2. Frame动画(帧动画)
帧动画的设计思想就像放电影一样,在onDraw()方法中使用invalidate()方法不断刷新View,以显示不同的图片序列。
代码实现过程:
首先创建一个AnimationDrawable对象,通过addFrame方法把每一帧要显示的内容添加进去,最后通过Start方法来播放动画。
frameAnimation = new AnimationDrawable(); for (int i = 0; i < 10; i++) { int id = getResources().getIdentifier("load" + (i+1), "drawable", this.getContext().getPackageName()); frameAnimation.addFrame(getResources().getDrawable(id), 100); } //设置循环播放 false表示循环 true表示不循环,仅播放一次 frameAnimation.setOneShot(false); //应用动画 image.setBackgroundDrawable(anim); anim.start();
xml实现方式: frame_anim.xml
<?xml version="1.0" encoding="utf-8"?> <animaltion-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/load1" android:duration="50" /> <item android:drawable="@drawable/load2" android:duration="50" /> <item android:drawable="@drawable/load3" android:duration="50" /> <item android:drawable="@drawable/load4" android:duration="50" /> <item android:drawable="@drawable/load5" android:duration="50" /> <item android:drawable="@drawable/load6" android:duration="50" /> <item android:drawable="@drawable/load7" android:duration="50" /> <item android:drawable="@drawable/load8" android:duration="50" /> <item android:drawable="@drawable/load9" android:duration="50" /> <item android:drawable="@drawable/load10" android:duration="50" /> </animaltion-list>
应用frame_anim.xml:
image.setBackgroundResource(R.anim.frame); //将动画资源文件设置为ImageView的背景 AnimationDrawable anim = (AnimationDrawable) image.getBackground(); //获取ImageView背景,此时已被编译成AnimationDrawable anim.start(); //开始动画
3. 属性动画
属性动画更改的是对象的实际属性,而补间动画改变的是View的绘制效果。
(1) ValueAnimator
ValueAnimator是用于处理动画属性值的主要属性动画时序引擎。它有所有的计算动画值的核心功能,并包含每个动画的时序细节,动画是否重复的信息,监听接收更新事件和设置评估定制类型的能力。ValueAnimator对象保持着动画的时间轨迹,如动画的运行时间及动画属性的当前值。
要启动一个动画,就要创建一个ValueAnimator对象,并且给该对象设置想要的动画属性的开始和结束值,以及动画持续实际。在调用start()方法启动动画时,整个动画期间,ValueAnimator对象会根据动画的持续时间和已经执行的时间比计算出一个时间因子(0~1),然后根据TimeInterpolator计算出另一个因子,最后TypeAnimator根据该因子和开始值结束值计算出属性值。TimeInterpolator定义了属性值在开始值与结束值之间的插值方法。
例子:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); animation.setDuration(1000); animation.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimatiorUpdate(ValueAnimator animation) { } }); animation.setInterpolator(new CycleInterpolator(3)); animation.start();
ValueAnimator.AnimatorUpdateListener中的onAnimationUpdate()回调方法用于监听属性的值更新时执行相应的操作,这是ValueAnimator必须监听的事件。
(2) ObjectAnimator
ObjectAnimator继承于ValueAnimator,用来指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性。使用ObjectAnimator应该满足条件:
- 动画效果的属性必须有一个set<propertyName>格式的设置器方法。例如,如果属性名为foo,那么就需要有一个setFoo()方法。
- 如果只在ObjectAnimator类中指定了一个values参数,那么该值会被假定为动画的结束值。因此需要有一个获取属性的方法,用于获取动画的开始值。例如,属性名为foo,就必须有getFoo()方法。
- 动画属性的获取和设置方法取决于ObjectAnimator对象的开始和结束值的数据类型。
- 根据属性或对象上的动画效果,可能需要调用View对象上的invalidate()函数,在更新动画效果时,强制屏幕重绘自己。在onAnimatornUpdate()回调方法中做这件事。
如果不满足这些条件,则不能使用ObjectAnimator,而应该用ValueAnimator代替。
4. 与动画相关的一些函数及参数说明
表一 | ||
属性[类型] | 功能 | |
Duration[long] | 属性为动画持续时间 | 时间以毫秒为单位 |
fillAfter [boolean] | 当设置为true ,该动画转化在动画结束后被应用 | |
fillBefore[boolean] | 当设置为true ,该动画转化在动画开始前被应用 | |
interpolator | 指定一个动画的插入器 | 有一些常见的插入器 accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速- 动画插入器 其他的属于特定的动画效果 |
repeatCount[int] | 动画的重复次数 | |
RepeatMode[int] | 定义重复的行为 | 1:重新开始 2:plays backward |
startOffset[long] | 动画之间的时间间隔,从上次动画停多少时间开始执行下个动画 | |
zAdjustment[int] | 定义动画的Z Order的改变 | 0:保持Z Order不变 1:保持在最上层 -1:保持在最下层 |