前言:html
这篇文章比较适合有接触过android动画编程的开发人员,若是还未接触过,则先写个demo感觉下android动画实现原理再来读这篇文章,效果才好。java
如下是转帖正文:android
一 传统 View 动画(Tween/Frame)git
主要有 4 中:缩放、平移、渐变、旋转编程
文件位置: res/anim/filename.xml
编译资源的数据类型:an Animation
资源引用:
Java: R.anim.filename
XML: @[package:]anim/filename数据结构
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
布局文件必须有一个独立的根元素,能够是 <alpha>
,<scale>
, <translate>
, <rotate>
, <set>
(持有一组其它的动画元素,甚至能够是内嵌的 set 元素) 中的一个app
<set>
一个持有其它动画元素的容器 <alpha>
, <scale>
, <translate>
,<rotate>
或者其它 <set>
元素框架
属性
Android:interpolator
应用于动画的插值器。该值必须是一个指定了插值器资源的引用(不是一个插值器的类名),在平台中有缺省的插值器资源可使用,或者你能够建立本身的插值器资源,能够看下面关于插值器的讨论。
android:shareInterpolator
Boolean 值, true:表明在全部的子元素中共享同一个插值器ide
<alpha>
A fade-in or fade-out animation. Represents an AlphaAnimation. 一个渐入渐出的动画,对应的 java 类为 AlphaAnimation。函数
属性
android:fromAlpha
android:toAlpha
表明动画开始和结束时透明度,0.0 表示彻底透明,1.0 表示彻底不透明,Float 值
<scale>
能够实现动态调控件尺寸的效果,经过设置 pivotX 和 pivotY 你能够指定 image 缩放的中心点,好比:若是这些值是 0,则表示左上角,全部的缩放变化将沿着右下角的轨迹运动。对应的类为:ScaleAnimation
属性
android:fromXScale
android:toXScale
android:fromYScale
android:toYScale
Float 值,为动画起始到结束时,X、Y 坐标上的伸缩尺寸
0.0 表示收缩到没有
1.0 表示正常无伸缩
android:pivotX
android:pivotY
表明缩放的中轴点 X/Y 坐标,浮点值
若是咱们想表示中轴点为图像的中心,咱们能够把两个属性值定义成 0.5 或者 50%。
<translate>
表明一个水平、垂直的位移。对应的类为 TranslateAnimation. 属性
android:fromXDelta 属性表明起始 X 方向的位置
android:toXDelta
android:fromYDelta
android:toYDelta
表明动画起始或者结束 X / Y 方向上的位置,Float 或者百分比值
浮点数 num%、num%p 分别相对于自身或者父控件
若是以浮点数字表示,是一个绝对值,表明相对自身原始位置的像素值;
若是以 num%表示,表明相对于本身的百分比,好比 toXDelta 定义为 100%就表示在 X 方向上移动本身的 1 倍距离
若是以 num%p 表示,表明相对于父类组件的百分比。
<rotate>
是旋转动画,与之对应的 Java 类是 RotateAnimation
属性
android:fromDegrees
android:toDegrees
表明起始和结束的角度,浮点值,单位:度
android:pivotX 属性表明旋转中心的 X 坐标值
android:pivotY 属性表明旋转中心的 Y 坐标值
Float 值或者百分比
这两个属性也有三种表示方式,可是 X 轴都是相对方向都是 Left,Y 轴都是相对于 Top
浮点数、num%、num%p;
数字方式表明相对于自身左边缘的像素值,
num%方式表明相对于自身左边缘或顶边缘的百分比,
num%p 方式表明相对于父容器的左边缘或顶边缘的百分比
属性
android:fromDegrees
android:toDegrees
开始和结束时的弧度位置,单位是度,Float 值
调用代码
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump); image.startAnimation(hyperspaceJump);
另外,在动画中,若是咱们添加了 android:fillAfter="true"后,这个动画执行完以后保持最后的状态;android:duration="integer"表明动画持续的时间,单位为毫秒。
用于修改一个动画过程当中的速率,能够定义各类各样的非线性变化函数,好比加速、减速等
在 Android 中全部的插值器都是 Interpolator 的子类,经过 android:interpolator 属性你能够引用不一样的插值器。下面是几种插值器:
你能够经过下面的方式使用它们
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>
自定义插值器 若是你对系统提供的插值器不满意,咱们能够建立一个插值器资源修改插值器的属性,好比修改 AnticipateInterpolator 的加速速率,调整 CycleInterpolator 的循环次数等。为了完成这种需求,咱们须要建立 XML 资源文件,而后将其放于/res/anim 下,而后再动画元素中引用便可。咱们先来看一下几种常见的插值器可调整的属性:
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
咱们先来看一下几种常见的插值器可调整的属性:
<accelerateDecelerateInterpolator>
无
<accelerateInterpolator>
android:factor 浮点值,加速速率,默认为 1
<anticipateInterploator>
android:tension 浮点值,起始点后退的张力、拉力数,默认为 2
<anticipateOvershootInterpolator>
android:tension 同上 android:extraTension 浮点值,拉力的倍数,默认为 1.5(2 * 1.5)
<bounceInterpolator>
无
<cycleInterplolator>
android:cycles int,循环的个数,默认为 1
<decelerateInterpolator>
android:factor 浮点值,减速的速率,默认为 1
<linearInterpolator>
无
<overshootInterpolator>
浮点值,超出终点后的张力、拉力,默认为 2
好比:res/anim/my_overshoot_interpolator.xml:
<?xml version="1.0" encoding="utf-8"?> <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="7.0"/> This animation XML will apply the interpolator: <scale xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/my_overshoot_interpolator" android:fromXScale="1.0" android:toXScale="3.0" android:fromYScale="1.0" android:toYScale="3.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" />
若是简单的修改插值器的属性值还不可以知足咱们的需求,那么就本身来经过实现 Interpolator 接口来定义本身的插值器了 由于上面全部的 Interpolator 都实现了 Interpolator 接口,这个接口定义了一个方法:float getInterpolation(float input); 此方法由系统调用,input 表明动画的时间,在 0 和 1 之间,也就是开始和结束之间。
线性(匀速)插值器定义以下:
public float getInterpolation(float input) { return input; }
加速减速插值器定义以下:
public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; }
文件目录:res/drawable/filename.xml
编译资源数据类型 AnimationDrawable
资源引用:
Java: R.drawable.filename
XML: @[package:]drawable.filename
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
<animation-list>
必须做为根元素,包含一个或者多个根元素
属性:android:oneshot :true:只执行一次动画,false:循环执行
<item>
A single frame of animation. Must be a child of a
<animation-list>
element. 一帧独立动画,必须是<animation-list>
的子元素
属性
android:drawable
Drawable 资源,用于这一帧的图片
android:duration
Integer 类型.该帧的时长,单位为毫秒 milliseconds.
res/anim/rocket.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>
调用代码
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image); rocketImage.setBackgroundResource(R.drawable.rocket_thrust); rocketAnimation = (AnimationDrawable) rocketImage.getBackground(); rocketAnimation.start();
Property Animation 动画有两个步聚:
1.计算属性值
2.为目标对象的属性设置属性值,即应用和刷新动画
过程一:计算已完成动画分数 elapsed fraction 为了执行一个动画,你须要建立一个 ValueAnimator,而且指定目标对象属性的开始、结束值和持续时间。在调用 start 后的整个动画过程当中, ValueAnimator 会根据已经完成的动画时间计算获得一个 0 到 1 之间的分数,表明该动画的已完成动画百分比。0 表示 0%,1 表示 100%。
过程二:计算插值(动画变化率)interpolated fraction 当 ValueAnimator 计算完已完成动画分数后,它会调用当前设置的 TimeInterpolator,去计算获得一个 interpolated(插值)分数,在计算过程当中,已完成动画百分比会被加入到新的插值计算中。
过程三:计算属性值 当插值分数计算完成后,ValueAnimator 会根据插值分数调用合适的 TypeEvaluator 去计算运动中的属性值。
以上分析引入了两个概念:已完成动画分数(elapsed fraction)、插值分数( interpolated fraction )。
插值器:时间的函数,定义了动画的变化律。
插值器只需实现一个方法:getInterpolation(float input)
,其做用就是把 0 到 1 的 elapsed fraction 变化映射到另外一个 interpolated fraction。 Interpolator 接口的直接继承自TimeInterpolator
,内部没有任何方法,而TimeInterpolator
只有一个getInterpolation
方法,因此全部的插值器只需实现getInterpolation
方法便可。
传入参数是正常执行动画的时间点,返回值是调用者真正想要它执行的时间点。传入参数是{0,1},返回值通常也是{0,1}。{0,1}表示整段动画的过程。中间的 0.二、0.3 等小数表示在整个动画(本来是匀速的)中的位置,其实就是一个比值。若是返回值是负数,会沿着相反的方向执行。若是返回的是大于 1,会超出正方向执行。也就是说,动画可能在你指定的值上下波动,大多数状况下是在指定值的范围内。
getInterpolation(float input)
改变了默认动画的时间点 elapsed fraction,根据时间点 interpolated fraction 获得的是与默认时间点不一样的属性值,插值器的原理就是经过改变实际执行动画的时间点,提早或延迟默认动画的时间点来达到加速/减速的效果。动画插值器目前都只是对动画执行过程的时间进行修饰,并无对轨迹进行修饰。
简单点解释这个方法,就是当要执行 input 的时间时,经过 Interpolator 计算返回另一个时间点,让系统执行另一个时间的动画效果。
Evaluators 告诉属性动画系统如何去计算一个属性值。它们经过 Animator 提供的动画的起始和结束值去计算一个动画的属性值。 属性系统提供了如下几种 Evaluators: 1.IntEvaluator
2.FloatEvaluator
3.ArgbEvaluator
这三个由系统提供,分别用于计算 int,float,color 型(十六进制)属性的计算器
4.TypeEvaluator
一个用于用户自定义计算器的接口,若是你的对象属性值类型,不是 int,float,或者 color 类型,你必须实现这个接口,去定义本身的数据类型。
TypeEvaluator
接口只有一个方法,就是evaluate()
方法,它容许你使用的 animator 返回一个当前动画点的属性值。
TimeInterpolator 和 TypeEvaluator 的区别
首先明确动画属性值的计算包括三步,其中第二步和第三步分别须要借助TimeInterpolator
和TypeEvluator
完成。
TypeEvaluator
所作的是根据数据结构计算最终的属性值,容许你定义本身的数据结构,这是官方对它的真正定义,若是你所定义的属性值的数据类型不是 float、int、color 类型,那么你须要实现 TypeEvaluator 接口的evaluate()
方法,本身进行属性值的计算
Interpolator
更倾向于你定义一种运动的变化率,好比匀速、加速、减速等,官方对 Interpolator 的定义也确实是这样的:
A time interpolator defines the rate of change of an >animation. This allows animations to have non-linear >motion, such as acceleration and deceleration.
对于自定义高级动画时,弄清TimeInterpolator
和TypeEvaluator
很是重要,若是你但愿要自定义本身的动画,那么这两个函数确定是关键部分,一个是定义动画变化率,一个是定义数据结构和属性值计算方式,二者共同决定了一个动画的运动。
属性动画中的主要的时序引擎,如动画时间,开始、结束属性值,相应时间属性值计算方法等。包含了全部计算动画值的核心函数。也包含了每个动画时间上的细节,信息,一个动画是否重复,是否监听更新事件等,而且还能够设置自定义的计算类型。
使用 ValueAnimator 实现动画须要手动更新:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); animation.setDuration(1000); animation.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Log.i("update", ((Float) animation.getAnimatedValue()).toString()); } }); animation.setInterpolator(new CycleInterpolator(3)); animation.start();
继承自ValueAnimator
,容许你指定要进行动画的对象以及该对象的一个属性。该类会根据计算获得的新值自动更新属性。也就是说上 Property Animation 的两个步骤都实现了。大多数的状况,你使用ObjectAnimator
就足够了,由于它使得目标对象动画值的处理过程变得简单,不用再向ValueAnimator
那样本身写动画更新的逻辑。但ObjectAnimator
有必定的限制,好比它须要目标对象的属性提供指定的处理方法,这个时候你须要根据本身的需求在ObjectAnimator
和ValueAnimator
中作个选择了,看哪一种实现更简便。
ObjectAnimator
的自动更新功能,依赖于属性身上的setter
和getter
方法,因此为了让ObjectAnimator
可以正确的更新属性值,你必须听从如下规范:
get
和set
方法(方法的格式必须是驼峰式),方法格式为 set(),由于 ObjectAnimator 会自动更新属性,它必须可以访问到属性的setter
方法,好比属性名为foo
,你就须要一个setFoo()
方法,若是 setter 方法不存在,你有三种选择:AnimatorProxy
。(这 3 点的意思总结起来就是必定要有一个setter
方法,让ObjectAnimator
可以访问到)
若是你为 ObjectAnimator 的工厂方法的可变参数只传递了一个值,那么会被做为动画的结束值。
注意,属性的getter
方法和setter
方法必须必须是相对应的,好比你构造了一个以下的ObjectAnimator
,那么getter
和setter
方法就应该为:
targetObject.setPropName(float) 和 targetObject.getPropName(float) : ObjectAnimator.ofFloat(targetObject, "propName", 1f)
invalidate
方法,根据新的动画值去强制屏幕重绘该 View。能够在onAnimateonUpdate()
回调方法中去作。好比,对一个 Drawable 的颜色属性进行动画,只有当对象重绘自身的时候,才会致使该属性的更新,(不像平移或者缩放那样是实时的)。一个 View 的全部 setter 属性方法,好比setAlpha()
和setTranslationX()
均可以适当的更新 View。所以你不须要在重绘的时候为这些方法传递新的值。更多关于 Listener 的信息,能够参考第四部分 Animation Listeners。简单总结下: 当你不但愿向外暴露Setter
方法的时候,或者但愿获取到动画值统一作处理的话,亦或只须要一个简单的时序机制(拥有动画的各类值)的话,那么你能够选择使用ValueAnimator
,它更简单。若是你就是但愿更新动画,为了简便,可使用ObjectAnimator
,但自定义的属性必须有setter
和getter
方法,而且它们必须都是标准的驼峰式(确保内部可以调用),必须有结束值。你能够实现Animator.AnimatorListener
接口根据本身的需求去更新 View。
提供组合动画能力的类。并可设置组中动画的时序关系,如同时播放、有序播放或延迟播放。Elevator
会告诉属性动画系统如何计算一个属性的值,它们会从Animator
类中获取时序数据,好比开始和结束值,并依据这些数据计算动画的属性值。
小结: TypeEvaluator
定义了属性值的计算方式,有 int,float,color 类型,根据属性的开始、结束值和插值一块儿计算出当前时间的属性值,终极方法,整个动画属性值计算过程的结尾。
TimeInterpolation
插值器都必须实现的接口,定义了动画的变化率,如线性,非线性。
ValueAnimator
与ObjectAnimator
:
二者均可以进行属性动画,可是ObjectAnimator
更加简单,不用去作更新属性值的计算,可是必需要提供标准的setter
和getter
方法,让ObjectAnimator
可以获取和更新属性值。
能够方便的为某个 View 的多个属性添加并行的动画,只使用一个ViewPropertyAnimator
对象就能够完成。它的行为更像一个ObjectAnimator
,由于它修改的是对象的实际属性值。但它为一次性给多个属性添加动画提供了方便,并且使用ViewPropertyAnimator
的代码更连贯更易读。
下面的代码段分别展现了使用多个ObjectAnimator
对象、一个ObjectAnimator
对象、 ViewPropertyAnimator
同时为一个 View 的 X 和 Y 属性添加动画的示例:
多个 ObjectAnimator 结合 AnimatorSet 实现
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
一个 ObjectAnimator 结合多个 PropertyValuesHolder 实现
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
ViewPropertyAnimator: 只需一行代码
myView.animate().x(50f).y(100f);//myView.animate()直接返回一个 ViewPropertyAnimator 对象
顾名思义,该类持有属性,相关属性值的操做以及属性的 setter,getter 方法的建立,属性值以 Keyframe 来承载,最终由 KeyframeSet 统一处理。
一个keyframe
对象由一对 time / value 的键值对组成,能够为动画定义某一特定时间的特定状态。
每一个keyframe
能够拥有本身的插值器,用于控制前一帧和当前帧的时间间隔间内的动画。
Keyframe.ofFloat(0f,0f);
第一个参数为:要执行该帧动画的时间节点(elapsed time / duration)
第二个参数为属性值。
所以若是你想指定某一特定时间的特定状态,那么简单的使用 ObjectAnimator
就知足不了你了,由于,ObjectAnimator.ofInt(....)
相似的工厂方法,没法指定特定的时间点的状态。
每一个 KeyFrame 的 Interpolator
每一个KeyFrame
其实也有个Interpolator
。若是没有设置,默认是线性的。以前为Animator
设置的Interpolator
是整个动画的,而系统容许你为每一KeyFrame
的单独定义Interpolator
,系统这样作的目的是容许你在某一个keyFrame
作特殊的处理,也就是总体上是按照你的插值函数来计算,可是,若是你但愿某个或某些KeyFrame
会有不一样的动画表现,那么你能够为这个keyFrame
设置Interpolator
。
所以,Keyframe 的定制性更高,你若是想精确控制某一个时间点的动画值及其运动规律,你能够本身建立特定的 Keyframe
Keyframe 使用
为了实例化一个keyframe
对象,你必须使用某一个工厂方法:ofInt(), ofFloat(), or ofObject() 去获取合适的keyframe
类型,而后你调用ofKeyframe
工厂方法去获取一个PropertyValuesHolder
对象,一旦你拥有了该对象,你能够将 PropertyValuesHolder 做为参数获取一个Animator
,以下:
Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);//动画属性名,可变参数 ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation) rotationAnim.setDuration(5000);
根据 Animator 传入的值,为当前动画建立一个特定类型的 KeyFrame 集合。
一般经过 ObjectAnimator.ofFloat(...)进行赋值时,这些值实际上是经过一个 KeyFrameSet 来维护的
好比:
ObjectAnimator.ofFloat(target, "translateX", 50, 100, 200);
调用者传入的 values 为 50,100,200,则 numKeyframs = 3,那么建立出相应的 Keyframe 为: Keyframe(0,50),Keyframe(1/2,100),Keyframe(1,200), 时间点 0,1/2,1 都是按比例划分的
public static KeyframeSet ofFloat(float... values) { int numKeyframes = values.length; FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)]; if (numKeyframes == 1) { keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f); keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]); } else { keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]); for (int i = 1; i < numKeyframes; ++i) { keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);//这里是关键 } } return new FloatKeyframeSet(keyframes); }
经过在 XML 中定义的动画,能够很方便的在多个 Activities 中重用并且更容易编辑,复用性强。为了区分新的属性动画,从 3.1 开始,你应res/animator/
下存放属性动画的资源文件,使用animator
文件夹是可选的,可是若是你想在 Eclipse ADT 插件中使用布局编辑工具(ADT 11.0.0+),就必须在res/animator
文件夹下存放了,由于 ADT 只会查找res/animator
文件夹下的属性动画资源文件。
属性动画支持的 Tag 有
ValueAnimator - <animator>
ObjectAnimator - <objectAnimator>
AnimatorSet - <set>
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
目录 res/animator/filename.xm
编译后的资源为
ValueAnimator
, ObjectAnimator
, or AnimatorSet
XML 文件的根元素必须为<set>
,<objectAnimator>
, or <valueAnimator>
之一。也能够在一个 set 中组织不一样的动画,包含其它<set>
元素,也就是说,能够嵌套。
<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>
<set>
动画集合节点,有一个属性 ordering,表示它的子动画启动方式是前后有序的仍是同时。
属性
sequentially:动画按照前后顺序
together (default) :动画同时启动
<objectAnimator>
一个对象的一个属性,相应的 Java 类为:ObjectAnimator
属性
android:propertyName:
String 类型,必需要设定的值,表明要执行动画的属性,经过名字引用,好比你能够指定了一个 View 的"alpha" 或者 "backgroundColor",这个 objectAnimator 元素没有暴露 target 属性,所以不可以在 XML 中执行一个动画,必须经过调用loadAnimator()
填充你的 XML 动画资源,而且调用setTarget()
应用到拥有这个属性的目标对象上。
android:valueTo
Float、int 或者 color,也是必须值,代表了动画结束的点,颜色由 6 位十六进制的数字表示。
android:valueFrom
相对应 valueTo,动画的起始点,若是没有指定,系统会经过属性身上的 get 方法获取,颜色也是 6 位十六进制的数字表示。
android:duration
动画的时长,int 类型,以毫秒为单位,默认为 300 毫秒。
android:startOffset
动画延迟的时间,从调用 start 方法后开始计算,int 型,毫秒为单位,
android:repeatCount
一个动画的重复次数,int 型,”-1“表示无限循环,”1“表示动画在第一次执行完成后重复执行一次,也就是两次,默认为 0,不重复执行。
android:repeatMode
重复模式:int 型,当一个动画执行完的时候应该如何处理。该值必须是正数或者是 -1,
“reverse”
会使得按照动画向相反的方向执行,可实现相似钟摆效果。
“repeat”
会使得动画每次都从头开始循环。
android:valueType
关键参数,若是该 value 是一个颜色,那么就不须要指定,由于动画框架会自动的处理颜色值。有 intType 和 floatType 两种:分别说明动画值为 int 和 float 型。
<animator>
在一个特定的时间里执行一个动画。相对应的是 ValueAnimator.全部的属性和同样 android:valueTo
android:valueFrom
android:duration
android:startOffset
android:repeatCount
android:repeatMode
android:valueType
Value Description
floatType (default)
res/animator/property_animator.xml:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
为了执行该动画,必须在代码中将该动画资源文件填充为一个 AnimationSet 对象,而后在执行动画前,为目标对象设置全部的动画集合。
简便的方法就是经过 setTarget 方法为目标对象设置动画集合,代码以下:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
view animation system 提供的能力只可以为 View 添加动画。所以若是你想为非 View 对象添加动画,就必须本身去实现, view animation system 在 View 动画的展示方面也是有约束的,只暴露了 View 的不多方面。好比 View 支持缩放和旋转,但不支持背景颜色的动画。
view animation system 的另外一劣势是,其改变的是 View 的绘制效果,真正的 View 的属性保持不变,好比不管你在对话中如何缩放 Button 的大小,Button 的有效点击区域仍是没有应用到动画时的区域,其位置与大小都不变。
可是 View animation system 只需花费不多时间建立并且只需不多的代码。若是 View 动画完成了你全部的动做,或者你存在的代码已经达到了你想要的效果,就不必使用 property 动画系统了。
彻底弥补了 View anim System 的缺陷,你能够为一个对象的任何属性添加动画,(View 或者非 View),同时对象本身也会被修改。 而且当属性变化的时候,property Anim 系统会自动的刷新屏幕。
属性动画系统在处理动画方面也更增强劲。更高级的,你能够指定动画的属性,好比颜色,位置,大小,定义动画的插值器而且同步多个动画。
而且在 Property Animation 中,改变的是对象的实际属性,如 Button 的缩放,Button 的位置与大小属性值都改变了。并且 Property Animation 不止能够应用于 View,还能够应用于任何对象。
平时使用的简单动画特效,使用 View 动画就能够知足,可是若是你想作的更加复杂,好比背景色的动画,或者不只是 View,还但愿对其它对象添加动画等,那么你就得考虑使用 Property 动画了。
更多动画开源库及使用,能够参考我的博客:Android 动画系列,其中介绍了一些基本使用,也提到了一些 GitHub 上的动画开源库,能够做为 Android 动画学习的资料
参考文献:
http://developer.android.com/guide/topics/resources/animation-resource.html#val-animator-element
http://blog.csdn.net/liuhe688/article/details/6660823
http://developer.android.com/guide/topics/resources/animation-resource.html#Property
http://developer.android.com/guide/topics/graphics/prop-animation.html
http://android-developers.blogspot.jp/2011/02/animation-in-honeycomb.html
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html
http://cogitolearning.co.uk/?p=1078
http://www.2cto.com/kf/201306/222725.html
http://my.oschina.net/banxi/blog/135633
http://zhouyunan2010.iteye.com/blog/1972789
http://blog.csdn.net/guolin_blog/article/details/43816093