通过<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;
}
}