什么是动画,动画的本质是通过连续不断地显示若干图像来产生“动”起来的效果。比如说一个移动的动画,就是在一定的时间段内,以恰当的速率(起码要12帧/秒以上,才会让人产生动起来的错觉)每隔若干时间在屏幕上更新一次位置。游戏中的动画效果也是由此而来。同样还有其他属性变更所引起的动画效果,从数学的角度来看,包括:(1)平移(2)旋转(3)缩放(4)透明度。当然这些属性可以组合起来使用,来达到更绚丽的画面。但是不论什么样的组合方式,我们都可以统一用Matirx运算来实现,从技术实现的角度来讲,Matrix是动画的核心,2D不用说,3D更是依赖矩阵(Matrix)的运算。当然,今天只是讲讲怎么实现动画效果,不会涉及这些基础知识~~
一、Tween Animation(补间动画)
补间动画可以实现View组件的移动、放大、缩小以及渐变等效果。也是我们使用动画效果时最常用的动画了。
一共有四种动画,分别为
|
AlphaAnimation |
渐变透明度动画效果 |
|
ScaleAnimation |
渐变尺寸伸缩动画效果 |
|
TranslateAnimation |
画面转换位置移动动画效果 |
|
RotateAnimation |
画面转移旋转动画效果 |
而设置动画也有两种方式,一种是在代码中设置,另一种就是在xml文件中配置。
-
设置alpha的动画
public Animation AlphaAnimation(){ Animation myAnimation_Alpha; //透明度从0到1 myAnimation_Alpha = new AlphaAnimation(0,1); //设置时间持续时间为 2000毫秒 myAnimation_Alpha.setDuration(2000); return myAnimation_Alpha; }
很简单,新建一个AlphaAnimation的类,里面放着要变化的起始参数和结束参数,然后程序就会自动演化出过场的动画。最后在要动画的view上设置
myAnimation = AlphaAnimation(); av.startAnimation(myAnimation);//av是一个imageview -
设置rotate的动画
public Animation RotateAnimation(){ Animation myAnimation_Rotate; //第一个参数fromDegrees为动画起始时的旋转角度 //第二个参数toDegrees为动画旋转到的角度 //第三个参数pivotXType为动画在X轴相对于物件位置类型 //第四个参数pivotXValue为动画相对于物件的X坐标的开始位置 //第五个参数pivotXType为动画在Y轴相对于物件位置类型 //第六个参数pivotYValue为动画相对于物件的Y坐标的开始位置 myAnimation_Rotate = new RotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); //动画插入器,可以自己定义动画的速度 //加速-减速 动画插入器 myAnimation_Rotate.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator); myAnimation_Rotate.setDuration(2000); return myAnimation_Rotate; }
里面有一个动画插入器的概念,这是控制动画过程速度的一个方法,比如上面代码中的accelerate_decelerate_interpolator就是要求动画先加速运行,在减速运行
-
设置Translate的动画
位移动画的参数很简单明了,就是对x,y位置的起始结束的地方做标记然后进行动画。view运行完动画后会恢复原来的状态public Animation TranslateAnimation(){ //TranslateAnimation(float fromXDelta, float toXDelta, //float fromYDelta, float toYDelta) //第一个参数fromXDelta为动画起始时 X坐标上的移动位置 //第二个参数toXDelta为动画结束时 X坐标上的移动位置 //第三个参数fromYDelta为动画起始时Y坐标上的移动位置 //第四个参数toYDelta为动画结束时Y坐标上的移动位置 Animation myAnimation_Translate; myAnimation_Translate=new TranslateAnimation(0.0f, -80.0f, 0.0f, 300.0f); myAnimation_Translate.setDuration(2000); myAnimation_Translate.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { av.setTranslationX(av.getTranslationX()-80f); av.setTranslationY(av.getTranslationY()+300f); } @Override public void onAnimationRepeat(Animation animation) { } }); return myAnimation_Translate; }
这里提到了一个监听器的概念,如上面的方法所示,可以对动画的开始时刻,结束时刻以及重复时刻进行监听,然后调用自己写入的方法。 -
设置Scale动画
public Animation ScaleAnimation(){ Animation myAnimation_Scale; //第一个参数fromX为动画起始时 X坐标上的伸缩尺寸 //第二个参数toX为动画结束时 X坐标上的伸缩尺寸 //第三个参数fromY为动画起始时Y坐标上的伸缩尺寸 //第四个参数toY为动画结束时Y坐标上的伸缩尺寸 /*说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 */ //第五个参数pivotXType为动画在X轴相对于物件位置类型 //第六个参数pivotXValue为动画相对于物件的X坐标的开始位置 //第七个参数pivotXType为动画在Y轴相对于物件位置类型 //第八个参数pivotYValue为动画相对于物件的Y坐标的开始位置 /*myAnimation_Scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); myAnimation_Scale.setDuration(2000);*/ //使用xml读取动画 myAnimation_Scale = AnimationUtils.loadAnimation(this,R.anim.scale); return myAnimation_Scale; }
这里我们使用读取anim文件夹下的xml文件来设置动画(若res文件夹下没有anim文件夹要自己创建)
xml内部内容如下:<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:interpolator= "@android:anim/accelerate_decelerate_interpolator" android:fromXScale="0.0" android:toXScale="1.4" android:fromYScale="0.0" android:toYScale="1.4" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> </set> <!-- 尺寸伸缩动画效果 scale 属性:interpolator 指定一个动画的插入器 在我试验过程中,使用android.res.anim中的资源时候发现 有三种动画插入器: accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator 减速- 动画插入器 其他的属于特定的动画效果 浮点型值: fromXScale 属性为动画起始时 X坐标上的伸缩尺寸 toXScale 属性为动画结束时 X坐标上的伸缩尺寸 fromYScale 属性为动画起始时Y坐标上的伸缩尺寸 toYScale 属性为动画结束时Y坐标上的伸缩尺寸 说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 pivotX 属性为动画相对于物件的X坐标的开始位置 pivotY 属性为动画相对于物件的Y坐标的开始位置 说明: 以上两个属性值 从0%-100%中取值 50%为物件的X或Y方向坐标上的中点位置 长整型值: duration 属性为动画持续时间 说明: 时间以毫秒为单位 布尔型值: fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用 -->
scale的参数可能有点多,其实也就是比Translate的动画多了设置中心点的参数,其他跟Translate类似,只不过scale是对x,y进行缩放而不是位移
-
AnimationsSet,动画集合
private AnimationSet mySet = new AnimationSet(true); public void AllAnimation(){ mySet.addAnimation(AlphaAnimation()); mySet.addAnimation(RotateAnimation()); mySet.addAnimation(TranslateAnimation()); mySet.addAnimation(ScaleAnimation()); mySet.setDuration(3000); av.startAnimation(mySet); }
动画集合可以将多个动画放到一个集合中,然后一起进行播放。(AnimationSet也是继承自Animation类,所以其它的属性跟单个动画差不多)
-
完整代码
View Codepublic class MyActivity extends Activity implements View.OnClickListener { private ImageView av; private Button alpha,rotate,translate,scale; private AnimationSet mySet; private Button allAnimation,back; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mySet = new AnimationSet(true); av = (ImageView)findViewById(R.id.imageView2); alpha = (Button)findViewById(R.id.alpha); alpha.setOnClickListener(this); rotate = (Button)findViewById(R.id.rotate); rotate.setOnClickListener(this); translate = (Button)findViewById(R.id.translate); translate.setOnClickListener(this); scale = (Button)findViewById(R.id.scale); scale.setOnClickListener(this); allAnimation = (Button)findViewById(R.id.all); allAnimation.setOnClickListener(this); back = (Button)findViewById(R.id.back); back.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.my, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public void onClick(View v) { Animation myAnimation = null; switch(v.getId()){ case R.id.alpha: myAnimation = AlphaAnimation(); av.startAnimation(myAnimation);//av是一个imageview break; case R.id.rotate: myAnimation = RotateAnimation(); av.startAnimation(myAnimation); break; case R.id.translate: myAnimation = TranslateAnimation(); av.startAnimation(myAnimation); break; case R.id.scale: myAnimation = ScaleAnimation(); av.startAnimation(myAnimation); break; case R.id.all: AllAnimation(); break; case R.id.back: this.finish(); break; } } public Animation AlphaAnimation(){ Animation myAnimation_Alpha; //透明度从0到1 myAnimation_Alpha = new AlphaAnimation(0,1); //设置时间持续时间为 2000毫秒 myAnimation_Alpha.setDuration(2000); return myAnimation_Alpha; } public Animation RotateAnimation(){ Animation myAnimation_Rotate; //第一个参数fromDegrees为动画起始时的旋转角度 //第二个参数toDegrees为动画旋转到的角度 //第三个参数pivotXType为动画在X轴相对于物件位置类型 //第四个参数pivotXValue为动画相对于物件的X坐标的开始位置 //第五个参数pivotXType为动画在Y轴相对于物件位置类型 //第六个参数pivotYValue为动画相对于物件的Y坐标的开始位置 myAnimation_Rotate = new RotateAnimation(0.0f, +350.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); //动画插入器,可以自己定义动画的速度 //加速-减速 动画插入器 myAnimation_Rotate.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator); myAnimation_Rotate.setDuration(2000); return myAnimation_Rotate; } public Animation TranslateAnimation(){ //TranslateAnimation(float fromXDelta, float toXDelta, //float fromYDelta, float toYDelta) //第一个参数fromXDelta为动画起始时 X坐标上的移动位置 //第二个参数toXDelta为动画结束时 X坐标上的移动位置 //第三个参数fromYDelta为动画起始时Y坐标上的移动位置 //第四个参数toYDelta为动画结束时Y坐标上的移动位置 Animation myAnimation_Translate; myAnimation_Translate=new TranslateAnimation(0.0f, -80.0f, 0.0f, 300.0f); myAnimation_Translate.setDuration(2000); myAnimation_Translate.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { av.setTranslationX(av.getTranslationX()-80f); av.setTranslationY(av.getTranslationY()+300f); } @Override public void onAnimationRepeat(Animation animation) { } }); return myAnimation_Translate; } public Animation ScaleAnimation(){ Animation myAnimation_Scale; //第一个参数fromX为动画起始时 X坐标上的伸缩尺寸 //第二个参数toX为动画结束时 X坐标上的伸缩尺寸 //第三个参数fromY为动画起始时Y坐标上的伸缩尺寸 //第四个参数toY为动画结束时Y坐标上的伸缩尺寸 /*说明: 以上四种属性值 0.0表示收缩到没有 1.0表示正常无伸缩 值小于1.0表示收缩 值大于1.0表示放大 */ //第五个参数pivotXType为动画在X轴相对于物件位置类型 //第六个参数pivotXValue为动画相对于物件的X坐标的开始位置 //第七个参数pivotXType为动画在Y轴相对于物件位置类型 //第八个参数pivotYValue为动画相对于物件的Y坐标的开始位置 /*myAnimation_Scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); myAnimation_Scale.setDuration(2000);*/ //使用xml读取动画 myAnimation_Scale = AnimationUtils.loadAnimation(this,R.anim.scale); return myAnimation_Scale; } public void AllAnimation(){ mySet.addAnimation(AlphaAnimation()); mySet.addAnimation(RotateAnimation()); mySet.addAnimation(TranslateAnimation()); mySet.addAnimation(ScaleAnimation()); mySet.setDuration(3000); av.startAnimation(mySet); } }