view动画之Tween Animation(补间动画)
在Android中,view动画有两种动画模式:Tween Animation(渐变动画)和 Frame Animation(帧动画)。渐变动画是通过对场景里的对象不断做图像变换(平移、缩放、旋转等)来产生动画效果。帧动画则是通过顺序播放 事先准备好的图像来产生动画效果,和电影类似。
1.通过Java代码实现Tween Animation
Tween Animation动画效果是通过Animation类来实现的。Animation类有五个 直接子类,分别为AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation 和AnimationSet。其中,AlphaAnimation用来实现透明度渐变动画效果;ScaleAnimation用来实现尺寸伸缩渐变动画效 果;TranslateAnimation用来实现画面转换位置移动动画效果;RotateAnimation用来实现画面转移旋转动画效 果;AnimationSet则用于对多个动画进行组合。
1.1AlphaAnimation类的常用方法 淡入淡出
AlphaAnimation类的常用方法如下:
AlphaAnimation(float fromAlpha, float toAlpha);
其中,参数fromAlpha表示动画起始时透明度;参数toAlpha表示动画结束时透明度(0.0表示完全透明,1.0表示完全不透明)
willChangeBounds();//动画是否影响指定的视图范围
willChangeTransformationMatrix();//动画是否影响转换矩阵
1.2ScaleAnimation类的常用方法 缩放效果
ScaleAnimation类的常用方法如下:
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
其中,参数fromX、toX分别表示起始和结束时x坐标上的伸缩尺寸;参数fromY、toY分别表示起 始和结束时y坐标上的伸缩尺寸;参数pivotXType、pivotYType分别表示x、y的伸缩模式;参数pivotXValue、 pivotYValue分别表示伸缩动画相对于x、y的坐标的开始位置。
1.3TranslateAnimation类的常用方法 移动效果
TranslateAnimation类的常用方法如下:
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta);
以自己的位置为起点+(设置的模式的X轴总长度*fromXDelta,设置的模式的Y轴总长度*fromYDelta)处开始移动,移动到 以自己的位置为起点+(设置的模式的X轴总长度*toXDelta,设置的模式的Y轴总长度*toYDelta)处
1.4RotateAnimation类的常用方法 旋转效果
RotateAnimation类的常用方法如下:
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue);
其中,参数fromDegrees表示开始时的角度;参数toDegrees表示结束时的角度;参数 pivotXType、pivotYType分别表示x、y的伸缩模式;参数pivotXValue、pivotYValue分别表示以自身为起点,移动(XValue,YValue)后的位置为圆心旋转。
1.5AnimationSet类的常用方法 装上面四种动画的集合
AnimationSet类的常用方法如下:
AddAnimation(Animation a);//添加一个动画到动画组件中
computeDurationHint();//动画组件的最大持续时间
getAnimation();//获取动画
getDuration();//获取动画组件的持续时间
getStartTime();//获取动画开始的时间
setDuration(long durationMillis);//设置动画持续时间
setFillAfter(boolean fillAfter);//如果为true,则动画执行后,控件将停留在执行结束的状态
setFillBefore(boolean fillBefore);//...............停留在执行前的状态
setStartOffset(long startOffset);//设置动画执行之前的等待时间
setRepeatMode(Animation.RESTART);//设置动画的重复模式
setRepeatCount(int repeatCount);//设置动画重复执行的次数
2.通过xml布局文件实现Tween Animation
使用xml布局文件可以更简单的实现Tween Animation动画效果。
Animation的xml布局文件存放在工程的res/anim目录下。
在xml布局文件中必须包含根元素<set>。节 点<alpha>、<scale>、<translate>和<rotate>分别对应 AlphaAnimation、ScaleAnimation、TranslateAnimation和RotateAnimation四种动画效果。 set就代表放动画效果的集合,可以一个动画有多种效果,也可以只有一个
2.1Tween Animation的共同节点属性
Tween Animation的共同节点属性有以下一些:
android:duration[long]//动画的持续时间,单位为ms
android:fillAfter[boolean]//设置为true时,动画转换在动画结束后被应用
android:fillBefore[boolean]//设置为true时,动画转换在动画开始前被应用
android:interpolator//设置动画的插入器,可选值有 accelerate_decelerate_interpolator加速减速动画插入器,accelerate_interpolator加速动画插 入器,decelerate_interpolator减速动画插入器
android:repeatCount[int]//动画的重复次数
android:repeatMode[int]//动画的重复模式,1表示重头开始重新播放,2表示从后往前重新播放
android:startOffset[long]//设置动画之间的时间间隔,多长时间后开始执行
android:zAdjustment[int]//
2.2节点<alpha>的常用属性
节点<alpha>的常用属性如下:
android:fromAlpha[float]表示起始时透明度
android:toAlpha[float]表示结束时透明度
取值说明:0.0表示完全透明,1.0表示完全不透明
2.3节点<scale>的常用属性
节点<scale>的常用属性如下:
android:fromXScale[float]表示动画起始时x坐标上的伸缩尺寸
android:toXScale[float]表示动画结束时x坐标上的伸缩尺寸
android:fromYScale[float]表示动画起始时y坐标上的伸缩尺寸
android:toYScale[float]表示动画结束时y坐标上的伸缩尺寸
取值说明:0.0表示收缩到没有,1.0表示正常无收缩,值大于1.0表示放大,值小于1.0表示收缩
android:pivotX[float]表示动画相对于物件的x坐标的开始位置
android:pivotY[float]表示动画相对于物件的y坐标的开始位置
2.4节点<translate>的常用属性
节点<translate>的常用属性如下:
android:fromXDelta[int]表示动画起始时x坐标上的位置
android:toXDelta[int]表示动画结束时x坐标上的位置
android:fromYDelta[int]表示动画起始时y坐标上的位置
android:toYDelta[int]表示动画结束时y坐标上的位置
2.5节点<rotate>的常用属性
节点<rotate>的常用属性如下:
android:fromDegrees表示动画起始时物件的角度
android:toDegrees表示动画结束时物件的角度
取值说明:负数from—正数to表示顺时针旋转,负数from—负数to表示逆时针旋转,正数from—正数to表示顺时针旋转,正数from—负数to表示逆时针旋转
android:pivotX表示动画相对于物件的x坐标的开始位置
android:pivotY表示动画相对于物件的y坐标的开始位置
3.实例
3.1在java代码中设置动画效果:
/* 使用Tweened Animations的步骤 1.创建一个AnimationSet对象 2.根据需要创建相应的Animation对象 3.根据需求为Animation对象设置相应的数据 4.将Animation对象添加到AnimationSet对象当中 5.使用控件对象开始执行AnimationSet
相对父亲与相对自己和绝对的这几种模式,起点都是在原来的位置上+相对的那个模式的X轴或Y轴的长度,切记指的是长度,而不是指那个位置 */ public class MainActivity extends Activity implements OnClickListener { private Button btn_Alpha; private Button btn_Scale; private Button btn_Rotate; private Button btn_Translate; private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); btn_Alpha = (Button) findViewById(R.id.btn_alpha); btn_Scale = (Button) findViewById(R.id.btn_scale); btn_Rotate = (Button) findViewById(R.id.btn_rotate); btn_Translate = (Button) findViewById(R.id.btn_translate); btn_Alpha.setOnClickListener(this); btn_Scale.setOnClickListener(this); btn_Rotate.setOnClickListener(this); btn_Translate.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_alpha://淡入淡出 AnimationSet animationSet=new AnimationSet(true);//为true代表共享shareInterpolator AlphaAnimation alpha=new AlphaAnimation(1f, 0f); alpha.setDuration(1500);//设置动画执行的时间(ms) animationSet.addAnimation(alpha);//1为不透明,0为完全透明 image.startAnimation(animationSet);//开始执行动画 break; case R.id.btn_scale://缩放 AnimationSet scaleSet=new AnimationSet(true); ScaleAnimation scale=new ScaleAnimation(1, 0.1f, 1, 0.1f,//XY抽的大小从1缩放到0.1(倍率) Animation.RELATIVE_TO_SELF, 0.5f, //以自己为参考,自己X轴长度的0.5倍 Animation.RELATIVE_TO_SELF, 0.5f);//以自己为参考,Y轴的0.5,以XY轴的交点为中心缩放 scale.setDuration(1500); scaleSet.addAnimation(scale); image.startAnimation(scaleSet); break; case R.id.btn_rotate://旋转 注意是以自己为起点,移动所设置的长度所在的位置为圆心 AnimationSet rotateSet=new AnimationSet(true); RotateAnimation rotate=new RotateAnimation(0, 360, //0到360度旋转,为负就是逆时针旋转 Animation.RELATIVE_TO_PARENT,0.5f, //在原来的位置上移动父控件X轴的0.5倍 Animation.RELATIVE_TO_PARENT,0.5f);//父控件Y轴的0.5倍,XY轴的交点为圆心旋转 rotate.setDuration(2000); rotateSet.addAnimation(rotate); image.startAnimation(rotateSet); break; case R.id.btn_translate://移动 AnimationSet translateSet=new AnimationSet(true); TranslateAnimation translate=new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1, //以自己的位置为起点,以自己为参考,自己X轴长度的0.5倍处,Y抽的1倍处开始移动 Animation.RELATIVE_TO_SELF, 1, //移动到X轴的1,Y轴的1倍长度的位置(这里也为相对于自己长度的倍数) Animation.RELATIVE_TO_SELF, 1); translate.setDuration(1500); translateSet.addAnimation(translate); translateSet.setFillAfter(true);//控件将停留在执行结束的状态 translateSet.setStartOffset(1000);//1秒后开始执行 image.startAnimation(translateSet); break; default: break; } } }
说明:以AnimationSet对象设置的属性对该对象所添加的所有效果都有效,new AnimationSet(true)中的true代表该动画集合中的所以效果共享动画的变化速度,即:
每个效果的变化速度都是一样的,否则需要对每个效果单独进行变化速度的设置
3.2在xml文件中设置动画效果:
使用xml文件实现动画效果的步骤:
1.在res文件夹下面新建一个名为anim的文件夹
2.创建xml文件,并首先加入set标签
3.在该标签当中加入rotate,alpha,scale或者translate标签
4.在java代码中使用AnimationUtils加载xml文件,并生成Animation对象
public class MainActivity2 extends Activity implements OnClickListener { private Button btn_Alpha; private Button btn_Scale; private Button btn_Rotate; private Button btn_Translate; private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); btn_Alpha = (Button) findViewById(R.id.btn_alpha); btn_Scale = (Button) findViewById(R.id.btn_scale); btn_Rotate = (Button) findViewById(R.id.btn_rotate); btn_Translate = (Button) findViewById(R.id.btn_translate); btn_Alpha.setOnClickListener(this); btn_Scale.setOnClickListener(this); btn_Rotate.setOnClickListener(this); btn_Translate.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_alpha://淡入淡出 Animation alpha = AnimationUtils.loadAnimation(this, R.anim.alpha);//引入xml文件 image.startAnimation(alpha); break; case R.id.btn_rotate://旋转+缩放效果的叠加 Animation rotate_scale = AnimationUtils.loadAnimation(this, R.anim.rotate_scale);//引入xml文件 image.startAnimation(rotate_scale); break; case R.id.btn_translate://移动 Animation translate=AnimationUtils.loadAnimation(this, R.anim.translate); translate.setAnimationListener(listener);//设置监听器 image.startAnimation(translate); break; default: break; } } //监听器的设置 AnimationListener listener=new AnimationListener() { @Override public void onAnimationStart(Animation animation) { System.out.println("动画效果开始执行时调用"); } @Override public void onAnimationRepeat(Animation animation) { System.out.println("动画效果重复执行时开始调用"); } @Override public void onAnimationEnd(Animation animation) { System.out.println("动画效果结束时开始调用"); } }; }
淡入淡出的xml文件:alpha.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true"> <alpha android:fromAlpha="1" android:toAlpha="0" android:duration="1000" android:startOffset="500"/> <!-- 执行时间1秒,500ms后开始执行 --> </set>
旋转加缩放效果叠加:rotate_scale.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:fromDegrees="0" android:toDegrees="-360" android:pivotX="50%p" android:pivotY="50%p" android:duration="3000"/> <!-- android:pivoX的值共有三种设置的方法: 1.android:pivoX="50" 这种方法使用绝对位置定位 2.android:pivoX="50%" 这种方法相对于控件本身定位 3.android:pivoX="50%p" 这种方法相对于控件的父控件定位 --> <scale android:fromXScale="1" android:toXScale="3" android:fromYScale="1" android:toYScale="3" android:duration="3000"/> <!-- 大于1表示放大,这里一个动画集合既有旋转又有扩大,使用时就会实现效果的叠加 --> </set>
移动的xml文件;translate.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="50%" android:toXDelta="100%" android:fromYDelta="50%" android:toYDelta="100%" android:duration="1500"/> <!--相对与控件本身定位,从控件本身X轴的50%移动到控件本身X轴的100% 从控件本身Y轴的50%移动到控件本身Y轴的100%--> </set>
4. interpolator的解释
android:interpolator="@android:anim/linear_interpolator" //在xml中使用
interpolator定义一个动画的变化率。这使得基本的动画效果(alpha, scale, translate, rotate)得以加速,减速,重复等。
AccelerateDecelerateInterpolator | 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速 |
AccelerateInterpolator | 在动画开始的地方速率改变比较慢,然后开始加速 |
CycleInterpolator | 动画循环播放特定的次数,速率改变沿着正弦曲线 |
DecelerateInterpolator | 在动画开始的地方速率改变比较慢,然后开始减速 |
LinearInterpolator | 在动画的以均匀的速率改变 |
在set标签中有一个属性叫 android:shareInterpolator(java代码中为:new AnimationSet(true);),传入一个boolean的值:true代表共享变化速率,就是set里面的
所有效果都是以这样是速率变化。如果传入的为false,代表不共享,就需要为每个效果定义速率
设置变化速率的方式:
translate.setInterpolator(new DecelerateInterpolator());//在动画开始的地方速率改变比较慢,然后开始减速
5.为activity设置活动之间的切换动画
//该方法需要写在startActivity或者finish()方法之后 overridePendingTransition(enterAnim, exitAnim);//重写挂起转变(进来动画和出去的动画) //int enterAnim:引用anim的xml文件 代表要移进来的那个activity 所以X轴坐标就是 100% 至 0 (可以用上面移动的xml文件做参考) //int exitAnim: 代表当前显示的要移出去的活动界面 所以X轴坐标就是 0 至 -100%,Y轴都是0