</pre>关于动画的实现,Android提供了Animation,在Android SDK介绍了2种Animation模式:<p></p><p><strong><span  ></span><span class="token li" ><span class="token md md-li" style="outline:none!important">1.</span>Tween Animation:通过对场景里的对象不断做图像变换(平移、缩放、旋转)产生动画效果,即是一种渐变动画;</span></strong></p><p><strong><span class="token li" ><span  style="outline:none!important"></span></span><span class="token li" ><span class="token md md-li" style="outline:none!important">2.</span>Frame Animation:顺序播放事先做好的图像,是一种画面转换动画。</span></strong></p><p><span class="token li" ><span  style="outline:none!important"></span></span><span  >动画类型</span><span  ></span><span  >下面先来看看Android提供的动画类型。Android的animation由四种类型组成</span><span  ></span><span  >在XML文件中:</span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">alpha 渐变透明度动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">scale 渐变尺寸伸缩动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">translate 画面转换位置移动动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">rotate 画面转移旋转动画效果</span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">在</span></span></p><p><span  >Java 源码中定义了相应的类,可以使用这些类的方法来获取和操作相应的属性:</span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">AlphaAnimation渐变透明度动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">ScaleAnimation渐变尺寸伸缩动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">TranslateAnimation画面转换位置移动动画效果</span></span></p><p><span style="color:#ff0000"><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important"></span><span  style="font-family:'microsoft yahei'; font-size:18px; line-height:29.7px; white-space:pre-wrap; outline:none!important">RotateAnimation画面转移旋转动画效果</span></span></p><p><span  ></span><span  >Tween Animation</span><span  ></span><span  >一个tween动画将对视图对象中的内容进行一系列简单的转换(位置,大小,旋转,透明性)。</span></p><p><span  >如果你有一个文本视图对象,你可以移动它,旋转它,让它变大或让它变小,如果文字下面还有背景图像,背景图像也会随着文件进行转换。</span><span  ></span><span  >使用XML来定义Tween Animation</span><span  ></span><span  >动画的XML文件在工程中res/anim目录,这个文件必须包含一个根元素,可以使<span class="token tag" style="color:rgb(52,52,52); font-weight:bold; font-size:0.9em; line-height:normal; font-family:'Source Code Pro',monospace; outline:none!important"><span class="token tag" style="font-size:0.9em; outline:none!important"><span class="token punctuation" style="outline:none!important; font-weight:normal"><</span>alpha</span><span class="token punctuation" style="outline:none!important; font-weight:normal">></span></span><span class="token tag" style="color:rgb(52,52,52); font-weight:bold; font-size:0.9em; line-height:normal; font-family:'Source Code Pro',monospace; outline:none!important"><span class="token tag" style="font-size:0.9em; outline:none!important"><span class="token punctuation" style="outline:none!important; font-weight:normal"><</span>scale</span><span class="token punctuation" style="outline:none!important; font-weight:normal">></span></span><span class="token tag" style="color:rgb(52,52,52); font-weight:bold; font-size:0.9em; line-height:normal; font-family:'Source Code Pro',monospace; outline:none!important"><span class="token tag" style="font-size:0.9em; outline:none!important"><span class="token punctuation" style="outline:none!important; font-weight:normal"><</span>translate</span><span class="token punctuation" style="outline:none!important; font-weight:normal">></span></span><span class="token tag" style="color:rgb(52,52,52); font-weight:bold; font-size:0.9em; line-height:normal; font-family:'Source Code Pro',monospace; outline:none!important"><span class="token tag" style="font-size:0.9em; outline:none!important"><span class="token punctuation" style="outline:none!important; font-weight:normal"><</span>rotate</span><span class="token punctuation" style="outline:none!important; font-weight:normal">></span></span>插值元素或者是把上面的元素都放入<span class="token tag" style="color:rgb(52,52,52); font-weight:bold; font-size:0.9em; line-height:normal; font-family:'Source Code Pro',monospace; outline:none!important"><span class="token tag" style="font-size:0.9em; outline:none!important"><span class="token punctuation" style="outline:none!important; font-weight:normal"><</span>set</span><span class="token punctuation" style="outline:none!important; font-weight:normal">></span></span>元素组中,默认情况下,所以的动画指令都是同时发生的,为了让他们按序列发生,需要设置一个特殊的属性<strong>startOffset</strong>。动画的指令定义了你想要发生什么样的转换,当他们发生了,应该执行多长时间,转换可以是连续的也可以使同时的。例如,你让文本内容从左边移动到右边,然后旋转180度,或者在移动的过程中同时旋转,没个转换需要设置一些特殊的参数(开始和结束的大小尺寸的大小变化,开始和结束的旋转角度等等,也可以设置些基本的参数(例如,开始时间与周期),如果让几个转换同时发生,可以给它们设置相同的开始时间,如果按序列的话,计算开始时间加上其周期。</span><span  ></span><span  >Tween Animation共同的节点属性</span></p><p><span  ></span><table border="1" cellspacing="0" cellpadding="0" ><tbody ><tr ><td valign="top" width="130" >属性[类型]</td><td valign="top" width="180" >功能</td><td valign="top" width="259" >备注</td></tr><tr ><td valign="top" width="130" >Duration[long]</td><td valign="top" width="180" >属性为动画持续时间</td><td valign="top" width="259" >时间以毫秒为单位</td></tr><tr ><td valign="top" width="130" >fillAfter [boolean]</td><td valign="top" width="438" colspan="2" >当设置为true ,该动画转化在动画结束后被应用</td></tr><tr ><td valign="top" width="130" >fillBefore[boolean]</td><td valign="top" width="438" colspan="2" >当设置为true ,该动画转化在动画开始前被应用</td></tr><tr ><td valign="top" width="130" ><p align="left" >interpolator</p></td><td valign="top" width="180" >指定一个动画的插入器</td><td valign="top" width="259" >有一些常见的插入器<br  />accelerate_decelerate_interpolator<br  />加速-减速 动画插入器<br  />accelerate_interpolator<br  />加速-动画插入器<br  />decelerate_interpolator<br  />减速- 动画插入器<br  />其他的属于特定的动画效果</td></tr><tr ><td valign="top" width="130" >repeatCount[int]</td><td valign="top" width="180" >动画的重复次数</td><td valign="top" width="259" > </td></tr><tr ><td valign="top" width="130" >RepeatMode[int]</td><td valign="top" width="180" >定义重复的行为</td><td valign="top" width="259" >1:重新开始 <wbr> 2:plays backward</wbr></td></tr><tr ><td valign="top" width="130" >startOffset[long]</td><td valign="top" width="438" colspan="2" >动画之间的时间间隔,从上次动画停多少时间开始执行下个动画</td></tr><tr ><td valign="top" width="130" >zAdjustment[int]</td><td valign="top" width="180" >定义动画的Z Order的改变</td><td valign="top" width="259" >0:保持Z Order不变<br  />1:保持在最上层<br  />-1:保持在最下层</td></tr></tbody></table><table border="1" cellspacing="0" cellpadding="0" ><tbody ><tr ><td valign="top" width="568" colspan="3" ><p align="center" >表二</p></td></tr><tr ><td valign="top" width="285" colspan="2" >XML节点</td><td valign="top" width="284" >功能说明</td></tr><tr ><td valign="top" width="285" colspan="2" >alpha</td><td valign="top" width="284" ><strong>渐变透明度动画效果</strong></td></tr><tr ><td valign="top" width="568" colspan="3" ><strong><alpha<br  />android:fromAlpha=”0.1″<br  />android:toAlpha=”1.0″<br  />android:duration=”3000″ /></strong></td></tr><tr ><td valign="top" width="83" >fromAlpha</td><td valign="top" width="202" ><p align="left" >属性为动画起始时透明度</p></td><td valign="top" rowspan="2" width="284" ><p style="margin:5px auto; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal">0.0表示完全透明<br  />1.0表示完全不透明<br  />以上值取0.0-1.0之间的float数据类型的数字</p><p style="margin:5px auto; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal">duration为动画持续时间,ms单位</p></td></tr><tr ><td valign="top" width="83" ><blockquote style="border:2px solid rgb(239,239,239); color:rgb(51,51,51); margin:0px; padding:4px; font-style:italic; background-color:initial"><p style="margin:5px auto; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal">toAlpha</p></blockquote></td><td valign="top" width="202" ><p style="margin:5px auto; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal">属性为动画结束时透明度</p></td></tr></tbody></table><table border="1" cellspacing="0" cellpadding="0" ><tbody ><tr ><td valign="top" width="568" colspan="4" ><p align="center" >表三</p></td></tr><tr ><td valign="top" width="285" colspan="2" >scale</td><td valign="top" width="284" colspan="2" ><strong>渐变尺寸伸缩动画效果</strong></td></tr><tr ><td valign="top" width="568" colspan="4" ><strong><scale<br  />android:interpolator= “@android:anim/accelerate_decelerate_interpolator”<br  />android:fromXScale=”0.0″<br  />android:toXScale=”1.4″<br  />android:fromYScale=”0.0″<br  />android:toYScale=”1.4″<br  />android:pivotX=”50%”<br  />android:pivotY=”50%”<br  />android:fillAfter=”false”<br  />android:startOffset=“700”<br  />android:duration=”700″<br  />android:repeatCount=”10″ /></strong></td></tr><tr ><td valign="top" width="121" >fromXScale[float] fromYScale[float]</td><td valign="top" width="180" colspan="2" >为动画起始时,X、Y坐标上的伸缩尺寸</td><td valign="top" rowspan="2" width="268" >0.0表示收缩到没有<br  />1.0表示正常无伸缩<br  />值小于1.0表示收缩<br  />值大于1.0表示放大</td></tr><tr ><td valign="top" width="121" >toXScale [float]<br  />toYScale[float]</td><td valign="top" width="180" colspan="2" >为动画结束时,X、Y坐标上的伸缩尺寸</td></tr><tr ><td valign="top" width="121" >pivotX[float]<br  />pivotY[float]</td><td valign="top" width="180" colspan="2" >为动画相对于物件的X、Y坐标的开始位置</td><td valign="top" width="268" >属性值说明:从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置</td></tr><tr ><td width="121" > </td><td width="164" > </td><td width="16" > </td><td width="268" > </td></tr></tbody></table><table border="1" cellspacing="0" cellpadding="0" ><tbody ><tr ><td valign="top" width="568" colspan="4" ><p align="center" >表四</p></td></tr><tr ><td valign="top" width="285" colspan="2" >translate</td><td valign="top" width="284" colspan="2" ><strong>画面转换位置移动动画效果</strong></td></tr><tr ><td valign="top" width="568" colspan="4" ><strong><translate<br  />android:fromXDelta=”30″<br  />android:toXDelta=”-80″<br  />android:fromYDelta=”30″<br  />android:toYDelta=”300″<br  />android:duration=”2000″ /></strong></td></tr><tr ><td valign="top" width="83" >fromXDelta<br  />toXDelta</td><td valign="top" width="296" colspan="2" >为动画、结束起始时 X坐标上的位置</td><td valign="top" width="189" > </td></tr><tr ><td valign="top" width="83" >fromYDelta<br  />toYDelta</td><td valign="top" width="296" colspan="2" >为动画、结束起始时 Y坐标上的位置</td><td valign="top" width="189" > </td></tr><tr ><td width="83" > </td><td width="202" > </td><td width="94" > </td><td width="189" > </td></tr></tbody></table><table border="1" cellspacing="0" cellpadding="0" ><tbody ><tr ><td valign="top" width="568" colspan="4" ><p align="center" >表五</p></td></tr><tr ><td valign="top" width="285" colspan="3" >rotate</td><td valign="top" width="284" ><strong>画面转移旋转动画效果</strong></td></tr><tr ><td valign="top" width="568" colspan="4" ><strong><rotate<br  />android:interpolator=”@android:anim/accelerate_decelerate_interpolator”<br  />android:fromDegrees=”0″<br  />android:toDegrees=”+350″<br  />android:pivotX=”50%”<br  />android:pivotY=”50%”<br  />android:duration=”3000″ /></strong></td></tr><tr ><td valign="top" width="92" >fromDegrees</td><td valign="top" width="161" >为动画起始时物件的角度</td><td valign="top" rowspan="2" width="315" colspan="2" >说明<br  />当角度为负数——表示逆时针旋转<br  />当角度为正数——表示顺时针旋转<br  />(负数from——to正数:顺时针旋转)<br  />(负数from——to负数:逆时针旋转)<br  />(正数from——to正数:顺时针旋转)<br  />(正数from——to负数:逆时针旋转)</td></tr><tr ><td valign="top" width="92" >toDegrees</td><td valign="top" width="161" >属性为动画结束时物件旋转的角度 可以大于360度</td></tr><tr ><td valign="top" width="92" >pivotX<br  />pivotY</td><td valign="top" width="161" >为动画相对于物件的X、Y坐标的开始位</td><td valign="top" width="315" colspan="2" >说明:以上两个属性值 从0%-100%中取值<br  />50%为物件的X或Y方向坐标上的中点位置</td></tr></tbody></table><span ></span>下面一个完整的动画实例res/anim/alpha.xml</p><p><span  ><?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:shareInterpolator="true">  <span style="white-space:pre"> </span><alpha        android:fromAlpha="0.0"        android:toAlpha="1.0"         android:duration="3000"        /> <span style="white-space:pre"></span></set></span></p><p><span  >java代码实例</span></p><p><span  ></span></p><pre name="code" class="java">public void anim(View v){
Animation animation =null;
switch (v.getId()) {
case R.id.alpha: //渐变透明度动画效果
animation = AnimationUtils.loadAnimation(this, R.anim.alpha); //绑定动画
animation.setFillAfter(true); //停留在最后的状态
imageView.startAnimation(animation); //启动动画
break;
case R.id.scale: //渐变尺寸伸缩动画效果
animation = AnimationUtils.loadAnimation(this, R.anim.scale); //绑定动画
animation.setFillAfter(true); //停留在最后的状态
imageView.startAnimation(animation); //启动动画
break;
case R.id.translate: //画面转换位置移动动画效果
animation = AnimationUtils.loadAnimation(this, R.anim.translat); //绑定动画
animation.setFillAfter(true); //停留在最后的状态
imageView.startAnimation(animation); //启动动画
break;
case R.id.rotate: //画面转移旋转动画效果
animation = AnimationUtils.loadAnimation(this, R.anim.rotate); //绑定动画
animation.setFillAfter(true); //停留在最后的状态
imageView.startAnimation(animation); //启动动画
break;
default:
break;
}

interpolator的解释

interpolator定义一个动画的变化率(the rate of change)。这使得基本的动画效果(alpha, scale, translate, rotate)得以加速,减速,重复等。


Interpolator 定义了动画的变化速度,可以实现匀速、正加速、负加速、无规则变加速等。Interpolator 是基类,封装了所有 Interpolator 的共同方法,它只有一个方法,即 getInterpolation (float input),该方法 maps a point on the timeline to a multiplier to be applied to the transformations of an animation。Android 提供了几个 Interpolator 子类,实现了不同的速度曲线,如下:


rpolator

在动画开始与介绍的地方速率改变比较慢,在中间的时候加速

AccelerateInterpolator

在动画开始的地方速率改变比较慢,然后开始加速

CycleInterpolator

动画循环播放特定的次数,速率改变沿着正弦曲线

DecelerateInterpolator

在动画开始的地方速率改变比较慢,然后开始减速

LinearInterpolator

在动画的以均匀的速率改变

 

Frame Animation

Frame Animation是顺序播放事先做好的图像,跟电影类似。不同于animation package, Android SDK提供了另外一个类AnimationDrawable来定义、使用Frame Animation。

Frame Animation可以在XML Resource定义(还是存放到res/anim文件夹下),也可以使用AnimationDrawable中的API定义。由于Tween Animation与Frame Animation有着很大的不同,因此XML定义的格式也完全不一样,其格式是:首先是animation-list根节点,animation-list根节点中包含多个item子节点,每个item节点定义一帧动画,当前帧的drawable资源和当前帧持续的时间。下面对节点的元素加以说明:


XML属性

说明

drawable

当前帧引用的drawable资源

duration

当前帧显示的时间(毫秒为单位)

oneshot

如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放。

variablePadding

If true, allows the drawable’s padding to change based on the current state that is selected.

visible

规定drawable的初始可见性,默认为flase;


下面定义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/girl_1" android:duration="200" />
<item android:drawable="@drawable/girl_2" android:duration="200" />
<item android:drawable="@drawable/girl_3" android:duration="200" />
<item android:drawable="@drawable/girl_4" android:duration="200" />
<item android:drawable="@drawable/girl_5" android:duration="200" />
<item android:drawable="@drawable/girl_6" android:duration="200" />
<item android:drawable="@drawable/girl_7" android:duration="200" />
<item android:drawable="@drawable/girl_8" android:duration="200" />
<item android:drawable="@drawable/girl_9" android:duration="200" />
<item android:drawable="@drawable/girl_10" android:duration="200" />
<item android:drawable="@drawable/girl_11" android:duration="200" />
</animation-list>

相关java代码


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bui_anim_frameanimation);

TextView textView = (TextView) this.findViewById(R.id.textView);
textView.setBackgroundResource(R.drawable.frame);//绑定Frame动画图形
final AnimationDrawable drawable = (AnimationDrawable) textView.getBackground();

getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
public boolean queueIdle() {
drawable.start();//启动动画
return false;
}
});


有一点需要强调的是:启动Frame Animation动画的代码rocketAnimation.start();不能在OnCreate()中,因为在OnCreate()中AnimationDrawable还没有完全的与ImageView绑定,在OnCreate()中启动动画,就只能看到第一张图片。这里实在拖曳事件中实现的。这里使用消息队列解决该问题;

下面,阅读Android SDK中对AnimationDrawable的介绍,有个简单的了解:


AnimationDrawable

获取、设置动画的属性

 

int getDuration()

获取动画的时长

int getNumberOfFrames()

获取动画的帧数


Void setOneShot(boolean oneshot)

获取oneshot属性

设置oneshot属性

void inflate(Resurce r,XmlPullParser p,

AttributeSet attrs)

 

增加、获取帧动画

Drawable getFrame(int index)

获取某帧的Drawable资源

void addFrame(Drawable frame,int duration)

为当前动画增加帧(资源,持续时长)

动画控制

void start()

开始动画

void run()

外界不能直接掉调用,使用start()替代


当前动画是否在运行

void stop()

停止当前动画