传统View动画与Property动画基础及比较

前言:

关于动画方面的知识也整理一段时间了,如题,这篇文章简单的介绍了View和Property动画的概念,如何在项目中创建资源文件,以及如何在代码中使用它们,本次整理动画的重点放在了Property动画上,下一篇文章将详细的分析Property动画几个重要的类,并分析几个开源库的实现,敬请期待。


View anim (Tween/Frame)


Tween动画


主要有4中:缩放、平移、渐变、旋转


传统View动画与Property动画基础及比较_第1张图片


文件位置: res/anim/filename.xml

编译资源的数据类型:an Animation.
资源引用:
Java: R.anim.filename
XML: @[package:]anim/filename
[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.     <set xmlns:android="http://schemas.android.com/apk/res/android"  
  3.         android:interpolator="@[package:]anim/interpolator_resource"  
  4.         android:shareInterpolator=["true" | "false"] >  
  5.         <alpha  
  6.         android:fromAlpha="float"  
  7.         android:toAlpha="float" />  
  8.         <scale  
  9.         android:fromXScale="float"  
  10.         android:toXScale="float"  
  11.         android:fromYScale="float"  
  12.         android:toYScale="float"  
  13.         android:pivotX="float"  
  14.         android:pivotY="float" />  
  15.         <translate  
  16.         android:fromXDelta="float"  
  17.         android:toXDelta="float"  
  18.         android:fromYDelta="float"  
  19.         android:toYDelta="float" />  
  20.         <rotate  
  21.         android:fromDegrees="float"  
  22.         android:toDegrees="float"  
  23.         android:pivotX="float"  
  24.         android:pivotY="float" />  
  25.         <set>  
  26.         ...  
  27.         </set>  
  28.     </set>  
布局文件必须有一个独立的根元素,可以是<alpha>, <scale>, <translate>, <rotate>, or <set>(持有一组其它的动画元素,甚至可以是内嵌的set元素) 中的一个

<set>
一个持有其它动画元素的容器(<alpha>, <scale>, <translate>, <rotate>) 或者其它 <set> 元素),代表一个动画集合
属性
android:interpolator(插值器)
应用于动画的插值器。该值必须是一个指定了插值器资源的引用(不是一个插值器的类名),在平台中有缺省的插值器资源可以使用,或者你可以创建自己的插值器资源,可以看下面关于插值器的讨论。
android:shareInterpolator

Boolean值, true:代表在所有的子元素中共享同一个插值器


<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值


调用代码
[java]  view plain copy
  1. ImageView image = (ImageView) findViewById(R.id.image);  
  2. Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);  
  3. image.startAnimation(hyperspaceJump);  
另外,在动画中,如果我们添加了android:fillAfter="true"后,这个动画执行完之后保持最后的状态;android:duration="integer"代表动画持续的时间,单位为毫秒。

插值器


用于修改一个动画过程中的速率,可以定义各种各样的非线性变化函数,比如加速、减速等。

在Android中所有的插值器都是Interpolator 的子类,通过 android:interpolator 属性你可以引用不同的插值器。下面是几种插值器:

传统View动画与Property动画基础及比较_第2张图片

你可以通过下面的方式使用它们

[html]  view plain copy
  1. <set android:interpolator="@android:anim/accelerate_interpolator">  
  2.         ...  
  3. </set>  

自定义插值器
如果你对系统提供的插值器不满意,我们可以创建一个插值器资源修改插值器的属性,比如修改AnticipateInterpolator的加速速率,调整CycleInterpolator的循环次数等。为了完成这种需求,我们需要创建XML资源文件,然后将其放于/res/anim下,然后再动画元素中引用即可。我们先来看一下几种常见的插值器可调整的属性:
[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.     <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"  
  3.         android:attribute_name="value"  
  4.  />  
我们先来看一下几种常见的插值器可调整的属性:
<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:
[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"  
  3. android:tension="7.0"/>  
  4.     This animation XML will apply the interpolator:  
  5.   
  6.     <scale xmlns:android="http://schemas.android.com/apk/res/android"  
  7.         android:interpolator="@anim/my_overshoot_interpolator"  
  8.         android:fromXScale="1.0"  
  9.         android:toXScale="3.0"  
  10.         android:fromYScale="1.0"  
  11.         android:toYScale="3.0"  
  12.         android:pivotX="50%"  
  13.         android:pivotY="50%"  
  14.         android:duration="700" />  
如果简单的修改插值器的属性值还不能够满足我们的需求,那么就自己来通过实现Interpolator接口来定义自己的插值器了
因为上面所有的Interpolator都实现了Interpolator接口,这个接口定义了一个方法:float getInterpolation(float input);
此方法由系统调用,input代表动画的时间,在0和1之间,也就是开始和结束之间。

线性(匀速)插值器定义如下:
[java]  view plain copy
  1. public float getInterpolation(float input) {    
  2.         return input;    
  3. }    
加速减速插值器定义如下:
[java]  view plain copy
  1. public float getInterpolation(float input) {    
  2.         return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;    
  3. }    

Frame动画


文件目录:res/drawable/filename.xml

编译资源数据类型 AnimationDrawable
资源引用:
Java: R.drawable.filename
XML: @[package:]drawable.filename

[java]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.    android:oneshot=["true" | "false"] >  
  4.     <item  
  5.         android:drawable="@[package:]drawable/drawable_resource_name"  
  6.         android:duration="integer" />  
  7. </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.
[html]  view plain copy
  1. res/anim/rocket.xml:  
  2.         <?xml version="1.0" encoding="utf-8"?>  
  3.         <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  4.             android:oneshot="false">  
  5.             <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />  
  6.             <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />  
  7.             <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />  
  8.         </animation-list>  

调用代码:

[java]  view plain copy
  1. ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);  
  2. rocketImage.setBackgroundResource(R.drawable.rocket_thrust);  
  3. rocketAnimation = (AnimationDrawable) rocketImage.getBackground();  
  4. rocketAnimation.start();</span>  


View anim与property anim 的比较


View anim 系统:

view animation system提供的能力只能够为View添加动画。因此如果你想为非View对象添加动画,就必须自己去实现,
view animation system在View动画的展现方面也是有约束的,只暴露了View的很少方面。比如View支持缩放和旋转,但不支持背景颜色的动画。
view animation system的另一劣势是,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用到动画时的区域,其位置与大小都不变。

但是View animation system只需花费很少时间创建而且只需很少的代码。如果View 动画完成了你所有的动作,或者你存在的代码已经达到了你想要的效果,就没必要使用property 动画系统了。


property anim 系统:

完全弥补了View anim System的缺陷,你可以为一个对象的任何属性添加动画,(View或者非View),同时对象自己也会被修改。

并且当属性变化的时候,property Anim系统会自动的刷新屏幕。

属性动画系统在处理动画方面也更加强劲。更高级的,你可以指定动画的属性,比如颜色,位置,大小,定义动画的插值器并且同步多个动画。

并且在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。


 Property Animation


传统View动画与Property动画基础及比较_第3张图片

目录: res/animator/filename.xm

编译后的资源为:ValueAnimator, ObjectAnimator, or AnimatorSet. 

XML文件的根元素必须为<set>, <objectAnimator>, or <valueAnimator>之一。也可以在一个set中组织不同的动画,包含其它<set>元素。也就是说,可以嵌套。

[html]  view plain copy
  1. <set  
  2.   android:ordering=["together" | "sequentially"]>  
  3.   
  4.     <objectAnimator  
  5.         android:propertyName="string"  
  6.         android:duration="int"  
  7.         android:valueFrom="float | int | color"  
  8.         android:valueTo="float | int | color"  
  9.         android:startOffset="int"  
  10.         android:repeatCount="int"  
  11.         android:repeatMode=["repeat" | "reverse"]  
  12.         android:valueType=["intType" | "floatType"]/>  
  13.   
  14.     <animator  
  15.         android:duration="int"  
  16.         android:valueFrom="float | int | color"  
  17.         android:valueTo="float | int | color"  
  18.         android:startOffset="int"  
  19.         android:repeatCount="int"  
  20.         android:repeatMode=["repeat" | "reverse"]  
  21.         android:valueType=["intType" | "floatType"]/>  
  22.   
  23.     <set>  
  24.         ...  
  25.     </set>  
  26. </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.所有的属性和<objectAnimator>一样
android:valueTo
android:valueFrom
android:duration
android:startOffset
android:repeatCount
android:repeatMode
android:valueType
Value Description
floatType (default)

res/animator/property_animator.xml:
[html]  view plain copy
  1. <set android:ordering="sequentially">  
  2.     <set>  
  3.         <objectAnimator  
  4.             android:propertyName="x"  
  5.             android:duration="500"  
  6.             android:valueTo="400"  
  7.             android:valueType="intType"/>  
  8.         <objectAnimator  
  9.             android:propertyName="y"  
  10.             android:duration="500"  
  11.             android:valueTo="300"  
  12.             android:valueType="intType"/>  
  13.     </set>  
  14.     <objectAnimator  
  15.         android:propertyName="alpha"  
  16.         android:duration="500"  
  17.         android:valueTo="1f"/>  
  18. </set>  

为了执行该动画,必须在代码中将该动画资源文件填充为一个AnimationSet对象,然后在执行动画前,为目标对象设置所有的动画集合。
简便的方法就是通过setTarget方法为目标对象设置动画集合,代码如下:
[java]  view plain copy
  1. AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,  
  2.    R.anim.property_animator);  
  3. set.setTarget(myObject);  
  4. set.start();  


平时使用的简单动画特效,使用View动画就可以满足,但是如果你想做的更加复杂,比如背景色的动画,或者不仅是View,还希望对其它对象添加动画等,那么你就得考虑使用Property动画了,随着Android应用慢慢对用户体验的重视,相信属性动画一定会大放异彩,以后一定会常和它打交道,所以在下一篇文章中,我会单独深入的分析属性动画,以及其实现原理,敬请期待。


参考文献:
http://developer.android.com/guide/topics/resources/animation-resource.html#val-animator-element
http://blog.csdn.net/liuhe688/article/details/6660823

你可能感兴趣的:(传统View动画与Property动画基础及比较)