通过<scale>标签可以定义缩放补间动画。下面是一个标准示例:
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:fromXScale="0.2" android:fromYScale="0.2" android:interpolator="@android:anim/decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="1.0" android:toYScale="1.0" />
大多数的属性和<translate>标签的属性是相同的,而有些属性是<scale>独有的,比如
android:pivotX:表示沿X轴方向缩放的支点位置。如果该属性值为50%,则支点在沿X轴的中心位置。
android:pivotY:表示沿Y轴方向缩放的支点位置。如果该属性值为50%,则支点在沿Y轴的中心位置。
如果想通过Java代码实现缩放补间动画,可以创建ScaleAnimation对象。ScaleAnimation类构造方法的定义如下:
public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
通过ScaleAnimation类的构造方法可以设置上述6个属性值,设置其他属性的方法与移动补间动画相同。
简单示例代码:
public class Main extends Activity implements AnimationListener { private Animation toLargeAnimation; private Animation toSmallAnimation; private ImageView imageView; @Override public void onAnimationEnd(Animation animation) { if (animation.hashCode() == toLargeAnimation.hashCode()) imageView.startAnimation(toSmallAnimation); else imageView.startAnimation(toLargeAnimation); } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageview); toLargeAnimation = AnimationUtils.loadAnimation(this, R.anim.to_large); toSmallAnimation = AnimationUtils.loadAnimation(this, R.anim.to_small); toLargeAnimation.setAnimationListener(this); toSmallAnimation.setAnimationListener(this); imageView.startAnimation(toSmallAnimation); } }
旋转补间动画
通过<rotate>标签可以定义旋转补间动画。
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="10000" android:fromDegrees="0" android:interpolator="@anim/linear_interpolator" android:pivotX="200%" android:pivotY="300%" android:repeatCount="infinite" android:repeatMode="restart" android:toDegrees="360" />
其中有两个特殊属性:
android:fromDegrees:表示旋转的起始角度。
android:toDegrees:表示旋转的结束角度。
android:repeatCount:设置旋转的次数。该值默认值为0,表示只播放一次,不重复显示动画。如果想让动画永不停止,则将其设为infinite或-1.
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代码实现旋转补间动画,可以创建RotateAnimation对象。RotateAnimation类构造函数的定义如下:
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
简单的示例代码:
linear_interpolator.xml
<linearInterpolator xmlns:android="http://schemas.android.com/apk/res/android"/>
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>标签可以定义透明度补间动画。
<scale android:duration="2000" android:fromXScale="1.0" android:fromYScale="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="0.2" android:toYScale="0.2" />
<!--其中android:fromAlpha和android:toAlpha属性分别表示起始透明度和结束透明度,这两个属性的值都在0.0到1.0之间。属性值为0.0表示完全透明,属性值为1.0表示完全不透明。-->
如果想通过Java代码实现透明度,可以创建AlphaAnimation对象。AlphaAnimation类构造方法的定义如下:
public AlphaAnimation(float fromAlpha, float toAlpha)
通过AlphaAnimation类构造方法可以设置起始透明度和结束透明度。
示例代码如下:
missile.xml
<set xmlns:android="http://schemas.android.com/apk/res/android" > <alpha android:duration="2000" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.1" /> <translate android:duration="2000" android:fromXDelta="0" android:fromYDelta="0" android:interpolator="@android:anim/accelerate_interpolator" android:toXDelta="0" android:toYDelta="-380" /> <scale android:duration="2000" android:fromXScale="1.0" android:fromYScale="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toXScale="0.2" android:toYScale="0.2" /> </set>
如上所示,<set>标签作为XML根节点,所有在<set>标签中定义的动画会在同一时间开始,在混合动画效果的情况下,往往会使用<set>标签来组合动画效果。
public class MyImageView extends ImageView { public AnimationDrawable animationDrawable; public ImageView ivMissile; public Field field; @Override protected void onDraw(Canvas canvas) { try { //利用反射技术得到当前的帧号:当显示完最后一幅图像之后,将MyImageView组件隐藏,并显示炸弹的原始图像 field = AnimationDrawable.class.getDeclaredField("mCurFrame"); field.setAccessible(true); int curFrame = field.getInt(animationDrawable); if (curFrame == animationDrawable.getNumberOfFrames() - 1) { setVisibility(View.INVISIBLE); ivMissile.setVisibility(View.VISIBLE); } } catch (Exception e) { } super.onDraw(canvas); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } }
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) { 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) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @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); ivBlast.setVisibility(View.INVISIBLE); ivBlast.ivMissile = ivMissile; } }
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) { 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) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @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); ivBlast.setVisibility(View.INVISIBLE); ivBlast.ivMissile = ivMissile; } }