</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() | 停止当前动画 |