OPhone 2.0的2D动画实践(三)
旋转补间动画
通过<rotate>标签可以定义旋转补间动画。下面的代码定义了一个标准的旋转补间动画。
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"
- android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>
其中<rotate>标签有两个特殊的属性。它们的含义如下:
android:fromDegrees:表示旋转的起始角度。
android:toDegrees:表示旋转的结束角度。
在<rotate>标签中还使用如下两个属性设置旋转的次数和模式。
android:repeatCount:设置旋转的次数。该属性需要设置一个整数值。如果该值为0,表示不重复显示动画。也就是说,对于上面的旋转补间动画,只从0度旋转到360度,动画就会停止。如果属性值大于0,动画会再次显示该属性指定的次数。例如,如果android:repeatCount属性值为1。动画除了正常显示一次外,还会再显示一次。也就是说,前面的旋转补间动画会顺时针自转两周。如果想让补间动画永不停止,可以将android:repeatCount属性值设为"infinite"或-1。该属性的默认值是0。
android:repeatMode:设置重复的模式。默认值是restart。该属性只有当android:repeatCount设置成大于0的数或infinite才起作用。android:repeatMode属性值除了可以是restart外,还可以设为reverse,表示偶数次显示动画时会做与动画文件定义的方向相反的动作。例如,上面定义的旋转补间动画会在第1、3、5、...、2n - 1圈顺时针旋转,而在2、4、6、...、2n圈逆时针旋转。如果想使用Java代码来设置该属性,可以使用Animation类的setRepeatMode方法。该方法只接收一个int类型参数。可取的值是Animation.RESTART和Animation.REVERSE。
如果想通过Java代码实现旋转补间动画,可以创建android.view.animation.RotateAnimation对象。RotateAnimation类构造方法的定义如下:
- public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY);
通过RotateAnimation类的构造方法可以设置旋转开始角度(fromDegrees)、旋转结束角度(toDegrees)、旋转支点横坐标(pivotX)和旋转支点纵坐标(pivotY)。
旋转补间动画实例
本例实现了两颗行星绕着一颗恒星旋转的效果。其中恒星会顺时针和逆时针交替旋转(android:repeatMode属性值为reverse)。效果如图1所示。
图1 旋转的星系
两颗行星和一颗恒星分别对应于一个动画文件。行星对应的两个动画文件的内容如下:
- hesper.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"
- android:duration="5000" android:repeatMode="restart" android:repeatCount="infinite"/>
- earth.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"
- android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>
恒星对应的动画文件的内容如下:
- sun.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"
- android:duration="20000" android:repeatMode="reverse" android:repeatCount="infinite"/>
本例的主程序相对简单,只需要装载这3个动画文件,并开始动画即可,代码如下:
- package net.blogjava.mobile;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.widget.ImageView;
- public class Main extends Activity
- {
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- ImageView ivEarth = (ImageView) findViewById(R.id.ivEarth);
- ImageView ivHesper = (ImageView) findViewById(R.id.ivHesper);
- ImageView ivSun = (ImageView) findViewById(R.id.ivSun);
- Animation earthAnimation = AnimationUtils.loadAnimation(this,R.anim.earth);
- Animation hesperAnimation = AnimationUtils.loadAnimation(this,R.anim.hesper);
- Animation sunAnimation = AnimationUtils.loadAnimation(this, R.anim.sun);
- ivEarth.startAnimation(earthAnimation);
- ivHesper.startAnimation(hesperAnimation);
- ivSun.startAnimation(sunAnimation);
- }
- }
透明度补间动画
通过<alpha>标签可以定义透明度补间动画。下面的代码定义了一个标准的透明度补间动画。
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
- android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="2000" />
其中android:fromAlpha和android:toAlpha属性分别表示起始透明度和结束透明度。这两个属性的值都在0.0和1.0之间。属性值为0.0表示完全透明,属性值为1.0表示完全不透明。
如果想通过Java代码实现透明度补间动画,可以创建android.view.animation.AlphaAnimation对象。AlphaAnimation类构造方法的定义如下:
- public AlphaAnimation(float fromAlpha, float toAlpha);
通过AlphaAnimation类的构造方法可以设置起始透明度(fromAlpha)和结束透明度(toAlpha)
透明度补间动画实例
本例将前面介绍的多种动画效果进行结合实现了投掷炸弹,并爆炸的特效。在本例中采用的动画类型有帧动画、移动补间动画、缩放补间动画和透明度补间动画。
其中使用了帧动画播放了一个爆炸的GIF动画;使用移动补间动画实现了炸弹被投下仍然会向前移动的偏移效果;缩放补间动画实现了当炸弹被投下时逐渐缩小的效果。透明度补间动画实现了炸弹被投下时逐渐模糊的效果。当运行本例后,会在屏幕下方正中间显示一个炸弹,如图2所示。然后触摸这个炸弹,炸弹开始投掷,逐渐变小和模糊,如图3所示。当炸弹变得很小、很模糊时,会播放GIF动画来显示爆炸效果,并播放爆炸的声音。如图4所示。
图2 初始状态的炸弹
图3 炸弹逐渐变小和模糊
图4 炸弹爆炸的效果
本例的实现代码如下:
- package net.blogjava.mobile;
- import android.app.Activity;
- import android.graphics.drawable.AnimationDrawable;
- import android.media.MediaPlayer;
- import android.os.Bundle;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnTouchListener;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.Animation.AnimationListener;
- import android.widget.ImageView;
- public class Main extends Activity implements OnTouchListener,AnimationListener
- {
- private ImageView ivMissile;
- private MyImageView ivBlast;
- private AnimationDrawable animationDrawable;
- private Animation missileAnimation;
- @Override
- public boolean onTouch(View view, MotionEvent event)
- {
- // 触摸炸弹后,开始播放动画
- ivMissile.startAnimation(missileAnimation);
- return false;
- }
- @Override
- public void onAnimationEnd(Animation animation)
- {
- // 在播放投掷炸弹动画结束后,显示MyImageView组件,并将显示炸弹的ImageView组件隐藏
- ivBlast.setVisibility(View.VISIBLE);
- ivMissile.setVisibility(View.INVISIBLE);
- try
- {
- // 开始播放爆炸的声音
- MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bomb);
- mediaPlayer.stop();
- mediaPlayer.prepare();
- mediaPlayer.start();
- }
- catch (Exception e)
- {
- }
- animationDrawable.stop();
- // 播放爆炸效果动画
- animationDrawable.start();
- }
- @Override
- public void onAnimationRepeat(Animation animation)
- {
- }
- @Override
- public void onAnimationStart(Animation animation)
- {
- }
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- ivMissile = (ImageView) findViewById(R.id.ivMissile);
- ivMissile.setOnTouchListener(this);
- ivBlast = (MyImageView) findViewById(R.id.ivBlast);
- ivBlast.setBackgroundResource(R.anim.blast);
- Object backgroundObject = ivBlast.getBackground();
- animationDrawable = (AnimationDrawable) backgroundObject;
- ivBlast.animationDrawable = animationDrawable;
- missileAnimation = AnimationUtils.loadAnimation(this, R.anim.missile);
- missileAnimation.setAnimationListener(this);
- // 在程序启动后,将显示爆炸效果的MyImageView组件隐藏
- ivBlast.setVisibility(View.INVISIBLE);
- ivBlast.ivMissile = ivMissile;
- }
- }
总结
本文主要介绍了旋转补间动画和透明度补间动画。通过将四种补间动画结合使用,可以实现非常有趣的动画效果。