本讲内容:Android 动画入门指南
1、补间动画
2、逐帧动画
Android中动画的实现分两种方式,一种方式是补间动画 Teen Animation,就是说你定义一个开始和结束,中间的部分由程序运算得到。另一种叫逐帧动画 Frame Animation,就是说一帧一帧的连起来播放就变成了动画。有点Flash基础的同学理解起来会很容易。接下来我们一个一个学习。
一、补间动画 Teen Animation
Android中实现补间动画的思路是这样的,
1、首先用XML定义一个动画效果
2、依据这个XML使用AnimationUtils工具类创建一个Animationd对象
3、调用View组件的startAnimation方法实现动画。
接下来我们用一个例子来看一下。
1、创建一个项目 Lesson24_Animation,主Activity名字叫MainActivity.java
2、在res目录下创建一个anim目录,在目录下创建下面五个动画定义文件,需要注意的是这5个文件在是2.2下调试通过的,网上很多文档的xml是无法通过IDE的检查的,可能是新版本检查更严格了。
alpha_animation.xml
1
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
2
|
<
set
>
|
3
|
<
alpha
android:duration
=
"300"
android:toalpha
=
"1.0"
android:fromalpha
=
"0.5"
android:repeatmode
=
"restart"
android:repeatcount
=
"1"
android:interpolator
=
"@android:anim/accelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
>
|
4
|
<
alpha
android:duration
=
"3000"
android:toalpha
=
"1.0"
android:fromalpha
=
"0.5"
android:repeatmode
=
"restart"
android:repeatcount
=
"0"
android:interpolator
=
"@android:anim/accelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
>
|
5
|
</
alpha
></
alpha
></
set
>
|
composite_animation.xml
1
|
<
set
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:shareinterpolator
=
"false"
>
|
2
|
<
scale
android:duration
=
"700"
android:interpolator
=
"@android:anim/accelerate_decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:fillafter
=
"false"
android:pivoty
=
"50%"
android:pivotx
=
"50%"
android:toyscale
=
"0.6"
android:fromyscale
=
"1.0"
android:toxscale
=
"1.4"
android:fromxscale
=
"1.0"
>
|
3
|
</
scale
></
set
><
set
android:interpolator
=
"@android:anim/decelerate_interpolator"
>
|
4
|
<
scale
android:duration
=
"400"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:pivoty
=
"50%"
android:pivotx
=
"50%"
android:toyscale
=
"0.0"
android:fromyscale
=
"0.6"
android:toxscale
=
"0.0"
android:fromxscale
=
"1.4"
android:fillbefore
=
"false"
android:startoffset
=
"700"
>
|
5
|
<
rotate
android:duration
=
"400"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:pivoty
=
"50%"
android:pivotx
=
"50%"
android:toyscale
=
"0.0"
android:startoffset
=
"700"
android:todegrees
=
"-45"
android:fromdegrees
=
"0"
>
|
6
|
</
rotate
></
scale
></
set
>
|
rotate_animation.xml
1
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
2
|
<
set
>
|
3
|
<
rotate
android:duration
=
"4000"
android:interpolator
=
"@android:anim/decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:pivoty
=
"50%"
android:pivotx
=
"50%"
android:todegrees
=
"-1440"
android:fromdegrees
=
"0"
>
|
4
|
</
rotate
>
|
5
|
</
set
>
|
scale_animation.xml
1
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
2
|
<
set
>
|
3
|
<
scale
android:duration
=
"1000"
android:interpolator
=
"@android:anim/decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:fillafter
=
"false"
android:pivoty
=
"100%"
android:pivotx
=
"0%"
android:toyscale
=
"1.0"
android:fromyscale
=
"0.0"
android:toxscale
=
"1.0"
android:fromxscale
=
"0.0"
>
|
4
|
</
scale
>
|
5
|
<
scale
android:duration
=
"1000"
android:interpolator
=
"@android:anim/decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:fillafter
=
"false"
android:pivoty
=
"50%"
android:pivotx
=
"50%"
android:toyscale
=
"1.0"
android:fromyscale
=
"0.0"
android:toxscale
=
"1.0"
android:fromxscale
=
"0.0"
>
|
6
|
</
scale
>
|
7
|
</
set
>
|
translate_animation.xml
1
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
2
|
<
set
>
|
3
|
<
translate
android:duration
=
"2000"
android:interpolator
=
"@android:anim/decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:toydelta
=
"0"
android:fromydelta
=
"0"
android:toxdelta
=
"300"
android:fromxdelta
=
"0"
>
|
4
|
</
translate
>
|
5
|
<
translate
android:duration
=
"2000"
android:interpolator
=
"@android:anim/decelerate_interpolator"
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:startoffset
=
"2000"
android:toydelta
=
"0"
android:fromydelta
=
"0"
android:toxdelta
=
"-300"
android:fromxdelta
=
"0"
>
|
6
|
</
translate
>
|
7
|
</
set
>
|
3、MainActivity.java的内容如下:
01
|
package
android.basic.lesson24;
|
02
|
03
|
import
android.app.Activity;
|
04
|
import
android.os.Bundle;
|
05
|
import
android.view.View;
|
06
|
import
android.view.View.OnClickListener;
|
07
|
import
android.view.animation.Animation;
|
08
|
import
android.view.animation.AnimationUtils;
|
09
|
import
android.widget.ImageButton;
|
10
|
11
|
public
class
MainAnimation
extends
Activity {
|
12
|
/** Called when the activity is first created. */
|
13
|
@Override
|
14
|
public
void
onCreate(Bundle savedInstanceState) {
|
15
|
super
.onCreate(savedInstanceState);
|
16
|
setContentView(R.layout.main);
|
17
|
18
|
//定义UI组件
|
19
|
final
ImageButton ib1 = (ImageButton) findViewById(R.id.ImageButton01);
|
20
|
final
ImageButton ib2 = (ImageButton) findViewById(R.id.ImageButton02);
|
21
|
final
ImageButton ib3 = (ImageButton) findViewById(R.id.ImageButton03);
|
22
|
final
ImageButton ib4 = (ImageButton) findViewById(R.id.ImageButton04);
|
23
|
final
ImageButton ib5 = (ImageButton) findViewById(R.id.ImageButton05);
|
24
|
25
|
//定义监听器
|
26
|
OnClickListener ocl =
new
OnClickListener() {
|
27
|
28
|
@Override
|
29
|
public
void
onClick(View v) {
|
30
|
switch
(v.getId()) {
|
31
|
case
R.id.ImageButton01:
|
32
|
//创建Animation对象
|
33
|
Animation ani1 = AnimationUtils.loadAnimation(
|
34
|
getApplicationContext(), R.anim.alpha_animation);
|
35
|
//组件播放动画
|
36
|
ib1.startAnimation(ani1);
|
37
|
break
;
|
38
|
case
R.id.ImageButton02:
|
39
|
Animation ani2 = AnimationUtils.loadAnimation(
|
40
|
getApplicationContext(), R.anim.scale_animation);
|
41
|
ib2.startAnimation(ani2);
|
42
|
break
;
|
43
|
case
R.id.ImageButton03:
|
44
|
Animation ani3 = AnimationUtils.loadAnimation(
|
45
|
getApplicationContext(), R.anim.translate_animation);
|
46
|
ib3.startAnimation(ani3);
|
47
|
break
;
|
48
|
case
R.id.ImageButton04:
|
49
|
Animation ani4 = AnimationUtils.loadAnimation(
|
50
|
getApplicationContext(), R.anim.rotate_animation);
|
51
|
ib4.startAnimation(ani4);
|
52
|
break
;
|
53
|
case
R.id.ImageButton05:
|
54
|
Animation ani5 = AnimationUtils.loadAnimation(
|
55
|
getApplicationContext(), R.anim.composite_animation);
|
56
|
ib5.startAnimation(ani5);
|
57
|
break
;
|
58
|
}
|
59
|
60
|
}
|
61
|
62
|
};
|
63
|
64
|
//绑定监听器
|
65
|
ib1.setOnClickListener(ocl);
|
66
|
ib2.setOnClickListener(ocl);
|
67
|
ib3.setOnClickListener(ocl);
|
68
|
ib4.setOnClickListener(ocl);
|
69
|
ib5.setOnClickListener(ocl);
|
70
|
}
|
71
|
}
|
4、运行程序,查看结果
原始图
点击第一个按钮的透明度变化效果
点击第二个按钮的缩放效果,这里看到的是两个缩放效果同时作用叠加的效果。也就是说默认情况下效果是同时发生的,而不是先后执行的,除非你使用 startoffset属性指定。同学们看这一讲最重要的还是自己练习来体会。
点击第三个按钮的位移效果,这个例子里我们可以清楚看到android:startOffset="2000"的作用,数独按钮前2秒向右移了300像素,后2秒又回到原处,注意第二个translate中的负值参数,它清晰的告诉我们位移数据是相对自身当时位置的。
点击第五个按钮的复合动画效果,这个效果的代码我是直接粘贴的官方帮助文档里的代码,看着效果还不赖^_^
二、逐帧动画
我们知道,Android是不支持Gif动画的,也不建议使用Gif动画,比较不幸的是到Android 2.2版本为止也不支持APNG这种png动画格式,所以我们制作只能用多张png图片逐帧播放的方式来实现动画效果。下面我们用一个例子来学习一下逐帧动画。
1、新建一个项目 Lesson24_FrameAnimation , 主Acitivy名字叫 MainFrameAnimation.java
2、拷贝下列图片到 res/drawable目录下
2、在res/anim目录下,新建一个文件 firefox_animation.xml 内容如下:
01
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
02
|
<
animation
-list
=
""
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:oneshot
=
"false"
>
|
03
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_0"
>
|
04
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_1"
>
|
05
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_2"
>
|
06
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_3"
>
|
07
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_4"
>
|
08
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_5"
>
|
09
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_6"
>
|
10
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_7"
>
|
11
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_8"
>
|
12
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_9"
>
|
13
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_10"
>
|
14
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_11"
>
|
15
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_12"
>
|
16
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_13"
>
|
17
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_14"
>
|
18
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_15"
>
|
19
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_16"
>
|
20
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_17"
>
|
21
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_18"
>
|
22
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_19"
>
|
23
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_20"
>
|
24
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_21"
>
|
25
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_22"
>
|
26
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_23"
>
|
27
|
<
item
android:duration
=
"50"
android:drawable
=
"@drawable/firefox_animation_24"
>
|
28
|
</
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
item
></
animation
>
|
3、在res/layout/main.xml中写入如下内容:
01
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
02
|
<
linearlayout
xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
android:orientation
=
"vertical"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
>
|
03
|
04
|
<
textview
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:textsize
=
"20sp"
android:text
=
"Android逐帧动画示例"
>
|
05
|
06
|
<
imageview
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_margin
=
"10dp"
android:id
=
"@+id/ImageView01"
android:background
=
"@anim/firefox_animation"
>
|
07
|
</
imageview
>
|
08
|
09
|
<
button
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:textsize
=
"20sp"
android:text
=
"开始动画"
android:id
=
"@+id/Button01"
>
|
10
|
</
button
>
|
11
|
<
button
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:textsize
=
"20sp"
android:text
=
"停止动画"
android:id
=
"@+id/Button02"
>
|
12
|
</
button
>
|
13
|
</
textview
></
linearlayout
>
|
3、在MainFrameAnimation.javaz中的内容如下:
01
|
package
android.basic.lesson24;
|
02
|
03
|
import
android.app.Activity;
|
04
|
import
android.graphics.drawable.AnimationDrawable;
|
05
|
import
android.os.Bundle;
|
06
|
import
android.view.View;
|
07
|
import
android.view.View.OnClickListener;
|
08
|
import
android.widget.Button;
|
09
|
import
android.widget.ImageView;
|
10
|
11
|
public
class
MainFrameAnimaton
extends
Activity {
|
12
|
/** Called when the activity is first created. */
|
13
|
@Override
|
14
|
public
void
onCreate(Bundle savedInstanceState) {
|
15
|
super
.onCreate(savedInstanceState);
|
16
|
setContentView(R.layout.main);
|
17
|
18
|
// 定义UI组件
|
19
|
Button b1 = (Button) findViewById(R.id.Button01);
|
20
|
Button b2 = (Button) findViewById(R.id.Button02);
|
21
|
final
ImageView iv = (ImageView) findViewById(R.id.ImageView01);
|
22
|
23
|
// 定义点击监听器
|
24
|
OnClickListener ocl =
new
OnClickListener() {
|
25
|
26
|
@Override
|
27
|
public
void
onClick(View v) {
|
28
|
29
|
// 定义"动画可画"对象,我起的名字,你看着不顺眼就当不存在^_^
|
30
|
AnimationDrawable ad = (AnimationDrawable) iv.getBackground();
|
31
|
32
|
switch
(v.getId()) {
|
33
|
case
R.id.Button01:
|
34
|
//调用动画可画对象的开始播放方法
|
35
|
ad.start();
|
36
|
break
;
|
37
|
case
R.id.Button02:
|
38
|
//调用动画可画对象的停止播放方法
|
39
|
ad.stop();
|
40
|
break
;
|
41
|
}
|
42
|
}
|
43
|
};
|
44
|
45
|
//绑定监听器
|
46
|
b1.setOnClickListener(ocl);
|
47
|
b2.setOnClickListener(ocl);
|
48
|
}
|
49
|
}
|
4、运行程序,查看效果:
换个背景再来一张,可以看到png动画的透明就是不一般^_^
顺便提一下,我的这些可爱的小狐狸图标,是在APNG这个项目中找到的,感兴趣的朋友去搜搜APNG吧。
本讲就到这里吧。
图片直接链接的,显示不了的话,去源地址看吧。
转载自: http://android.yaohuiji.com/archives/tag/animationutils