合理的动画是一款优秀 App 不可缺少的一部分,Android 也为开发者提供了全套动画实现的 API。关于 Android 动画分类大致可分为以下三类:补间动画(Tween Animation),帧动画(Frame Animation),及 Android 3.0(API 10)以后新增的属性动画(Property Animation)。下面对其分别做一下介绍。
Tween Animation:补间动画,是指通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果,即是一种渐变动画;
Frame Animation:帧动画,是指按照一定的帧率顺序播放一组事先做好的图像,是一种画面转换动画;
Property Animation:属性动画,是指在设定的时间和速率下完成对象的属性由一个值变成另一个值的过程,它也是一种渐变动画。
注:属性动画是 Android 3.0 (API 10)以后新增的特性。如需兼容以前版本,则需要添加 nineoldandroid 动画兼容包。
Tween Animation定义在xml文件中。可以对view实现一系列的转换,例如:移动、渐变、伸缩、旋转。补间动画只能应用于 View 对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变。而且对于 Tween Animation,并不改变属性的值,它只是改变了View对象绘制的位置。
下面先来看看Android提供的动画类型。Android的animation由四种类型组成
在XML文件中:
alpha 渐变透明度动画效果
scale 渐变尺寸伸缩动画效果
translate 画面转换位置移动动画效果
rotate 画面转移旋转动画效果
在Java 源码中定义了相应的类,可以使用这些类的方法来获取和操作相应的属性:
AlphaAnimation 渐变透明度动画效果
ScaleAnimation 渐变尺寸伸缩动画效果
TranslateAnimation 画面转换位置移动动画效果
RotateAnimation 画面转移旋转动画效果
XML 文件路径:
res/anim/filename.xml // 小写文件名将作为资源的ID
资源引用:
在 Java 中:R.anim.filename
在 XML 中:@[package:]anim.filename
XML 结构:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:androidsetxmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"]> <alpha /> <scale /> <translate /> <rotate /> <set> ... </set> </set>
默认情况下,所以的动画指令都是同时发生的,为了让他们按序列发生,需要设置一个特殊的属性 startOffset 。动画的指令定义了你想要发生什么样的转换,当他们发生了,应该执行多长时间,转换可以是连续的也可以使同时的。例如,你让文本内容从左边移动到右边,然后旋转180度,或者在移动的过程中同时旋转,没个转换需要设置一些特殊的参数(开始和结束的大小尺寸的大小变化,开始和结束的旋转角度等等,也可以设置些基本的参数(例如,开始时间与周期),如果让几个转换同时发生,可以给它们设置相同的开始时间,如果按序列的话,计算开始时间加上其周期。
公共属性:
属性 [类型] | 功能 | 备注 |
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] | 本次动画 start 开始执行的偏移时长 | |
zAdjustment [int] | 定义动画的Z Order的改变 | -1:最下层;0:不变;1:最上层 |
注:元素属性值中使用%(in percentage relative to the object's top edge),%p(in percentage relative to the parent container's top edge )的单位。
用法:
// 获取 Animation 对象 Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.tween_anim); // 开始动画 view.startAnimation(animation);
注:startAnimation 必须为触发调用,不能在 onCreate 中调用。
样例:
<alpha android:fromAlpha="0.1" android:toAlpha="1.0" android:duration="3000" />
私有属性:
属性 [类型] | 功能 | 备注 |
fromAlpha [float] | 动画开始时的Alpha值 | 取值范围 [0.0, 1.0], 单位:float |
toAlpha [float] | 动画结束时的Alpha值 | 0.0 完全透明; 1.0 完全不透明 |
样例:
<scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.4" android:fromYScale="0.0" android:toYScale="1.4" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:startOffset="700" android:duration="700" android:repeatCount="10" />
私有属性:
属性 [类型] | 功能 | 备注 |
fromXScale [float] | 动画开始时 X 轴缩放值 | 取值范围 [0.0, 8.0], 单位:float |
fromYScale [float] | 动画开始时 Y 轴缩放值 | > 1.0 表示放大; < 1.0 表示缩小 |
toXScale [float] | 动画结束时 X 轴缩放值 | 0.0 表示缩小到无 |
toYScale [float] | 动画结束时 Y 轴缩放值 | 1.0 表示原大小无缩放 |
pivotX [float] |
动画作用中心 X 轴相对位置 | 取值[0%, 100%] 或 [0%p, 100%p] |
pivotY [float] | 动画作用中心 Y 轴相对位置 | 其区别,见上部分注意事项。 |
样例:
<translate android:fromXDelta="30" android:toXDelta="-80" android:fromYDelta="30" android:toYDelta="300" android:duration="2000" />
私有属性:
属性 [类型] | 功能 | 备注 |
fromXDelta [int, float] | 动画开始时 X 轴的位置 | int 单位像素 |
fromYDelta [int, float] | 动画开始时 Y 轴的位置 | 相对于控件起始位置(0, 0) |
toXDelta [int, float] | 动画结束时 X 轴的位置 | float 单位百分比 |
toYDelta [int, float] | 动画结束时 Y 轴的位置 | 取值、用法见上 |
样例:
<rotate android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromDegrees="0" android:toDegrees="+350" android:pivotX="50%" android:pivotY="50%" android:duration="3000" />
私有属性:
属性 [类型] | 功能 | 备注 |
fromDegress [int] | 动画开始时的旋转角度 | 角度差 > 0,顺时针旋转 |
toDegress [int] | 动画结束时的旋转角度 | 角度差 < 0,逆时针旋转 |
pivotX [float] | 动画作用中心 X 的相对位置 | 取值[0%, 100%] 或 [0%p, 100%p] |
pivotY [float] | 动画作用中心 Y 的相对位置 | 其区别,见上部分注意事项。 |
与影视动画或电影相似,Android 帧动画(FrameAnimation)也是一系列的图片按事先定好的速率顺序显示而形成的动画效果。帧动画也可以在 XML 中定义。
XML 文件路径
res/drawable/filename.xml // 小写文件名将作为资源的ID
资源引用
在 Java 中:R.drawable.filename
在 XML 中:@[package:]drawable.filename
XML 结构
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> </animation-list>
XML必须以 animation-list 作为根节点。其结构简单,就不对元素和属性单独做解释了,如真需了解详情请参阅官方帮助文档 —— Animation Resources。
用法
首先将 drawable 资源设置为背景,然后再获取并播放,
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image); rocketImage.setBackgroundResource(R.drawable.rocket_thrust); rocketAnimation = (AnimationDrawable) rocketImage.getBackground(); rocketAnimation.start();
注意事项
要在代码中调用 ImageView 的 setBackgroundResource 方法,如果直接在 XML 布局文件中设置其 src 属性当触发动画时会 ForceClose ;
在动画 start 之前要先 stop,不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次;
正如SDK中所提到的,不要在 onCreate 中调用 start,因为 AnimationDrawable 还没有完全跟 Window 相关联,如果想要界面显示时就开始动画的话,可以在 onWindowFoucsChanged 中调用 start 。
Property Animation 定义在xml文件中用以在一段时间内改变对象的某个或某些属性值,与Tween Animation不同,它不光展现对象的绘制图,他会实实在在改变对象的属性。
XML 文件路径:
res/animator/filename.xml // 小写文件名将作为资源的ID
资源引用:
在 Java 中:R.animator.filename
在 XML 中:@[package:]animator.filename
XML 结构:
<set android:ordering=["together" | "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <animator android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <set> ... </set> </set>
如需了解属性详情请参阅官方帮助文档 —— Animation Resources。
用法:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
为了理解插值器(Interpolator)的用处,我们在此要复习一下动画的原理。简单而言,动画是基于人的视觉原理,当多张图像幻灯片一样连续播放,播放速度>=24帧每秒(FPS)时所形成的动景错觉。动画中分关键帧和补间帧,关键帧能明显表达一种特定意义的画面,关键帧与关键帧之间需要平滑过度,这些过度画面就叫做补间帧。
Android 补间动画(Tween Animation)顾名思义是由 start 定义的开始关键帧,end 定义的结束关键帧,中间由插值器完成的补间帧所形成的简单动画形式。插值器就是一个形成补间帧的函数,时间是这个函数的输入,view 属性值是这个函数的输出。因此插值器不能决定动画的开始形态和结束形态,但它决定动画的变幻的路径和速率。
根据上面的介绍,我们就很容易明白插值器在补间动画(Tween Animation)和属性动画(Property Animation)中得到广泛应用。
系统自带插值器:
Interpolator class | Resource ID | 备注 |
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 加速减速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 退小步往前冲 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 退小步冲过头退回 |
BounceInterpolator | @android:anim/bounce_interpolator | 球落地弹动效果 |
CycleInterpolator | @android:anim/cycle_interpolator | 周期重复 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 减速 |
LinearInterpolator | @android:anim/linear_interpolator | 匀速 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 冲过头再退回 |
用户自定义插值器:
XML 文件路径
res/anim/filename.xml // 小写文件名将作为资源的ID
资源引用
在 XML 中:@[package:]anim.filename
XML 结构
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value"/>
如需了解更多详情请参阅官方帮助文档 —— Animation Resources。