Android 动画系列:
Android 动画–帧动画(Frame Animation)
Android 动画–补间动画(Tween Animation)
这篇文章我们总结另一种view动画,补间动画,这种动画比帧动画重要,也是我们平时经常用到的动画,虽然Android 3.0引入了 属性动画,但我们开发过程中的大多数动画效果还是可以通过补间动画来完成,因此我们很有必要深入学习和总结一下补间动画。
补间动画(Tween Animation)
Tween Animation就是只指定动画开始位置和结束位置,动画变化过程中的中间位置系统会自动为我们计算,从而实现动画。Tween Animation是对View进行一系列的动画操作,包括淡入淡出、缩放、平移、旋转四种,它的特点是通过对场景里的对象不断做图像变换(渐变、平移、缩放、旋转)产生动画效果。
抽象类Animation 位于 android.view.animation
中,Animation是补间动画的基类,它的直接子类AlphaAnimation, RotateAnimation, ScaleAnimation, TranslateAnimation, AnimationSet,提供了一系列的动画效果。
注意:
View 动画只改变了View的绘制效果,而实际属性值未变。比如当使用 View 动画移动一个按钮位置后,按钮点击的实际位置仍未改变。在代码中定义动画。
主要API如下表格:
xml 动画 | java代码 | 说明 |
---|---|---|
alpha | AlphaAnimation | 透明度渐变动画 |
scale | ScaleAnimation | 尺寸大小渐变动画 |
translate | TranslateAnimation | 位置移动动画 |
rotate | RotateAnimation | 位置旋转动画 |
set | SetAnimaton | 可以同时执行alpha、scale、translate、rotate或者其它set元素动画的集合 |
一个简单例子:
先看效果
每个动画我都会使用xml方式和Java代码的方式实现
AlphaAnimation
方式一:java代码
Animation alphaAnim = new AlphaAnimation(1, 0);
alphaAnim.setDuration(2000); //设置动画持续时间
alphaAnim.setRepeatCount(3); //设置重复次数
alphaAnim.setFillAfter(false); //动画执行完后是否停留在执行完的状态
alphaAnim.setStartOffset(0); //执行前的等待时间
mImgDog.startAnimation(alphaAnim);
方式二:xml
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000"
android:repeatCount="-1"
android:fillAfter="true"
android:fillBefore="false"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="100">
</alpha>
使用
AlphaAnimation alphaAnim = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_fade_in);
mImgDog.startAnimation(rotateAnim);
ScaleAnimation
方式一:java代码
Animation scaleAnim = new ScaleAnimation(0f, 1, 0f, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnim.setDuration(2000); //设置动画持续时间
scaleAnim.setRepeatCount(3);//设置重复次数
scaleAnim.setFillAfter(false); //动画执行完后是否停留在执行完的状态
scaleAnim.setStartOffset(0); //执行前的等待时间
mImgDog.startAnimation(scaleAnim);
方式二:xml
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration = "2000"
android:fillAfter ="true">
</scale>
使用
ScaleAnimation alphaAnim = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_scale_in);
mImgDog.startAnimation(rotateAnim);
TranslateAnimation
方式一:java代码
Animation translateAnim = new TranslateAnimation(0, 300, 0, 0);
translateAnim.setDuration(2000); //设置动画持续时间
translateAnim.setRepeatCount(3); //设置重复次数
translateAnim.setFillAfter(false); //动画执行完后是否停留在执行完的状态
translateAnim.setStartOffset(0); //执行前的等待时间
mImgDog.startAnimation(translateAnim);
方式二:xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="300"
android:fromYDelta="0"
android:toYDelta="0"
android:duration = "2000"
android:fillAfter ="true">
</translate>
使用
TranslateAnimation translateAnim = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_translate_in);
mImgDog.startAnimation(rotateAnim);
RotateAnimation
方式一:java代码
Animation rotateAnim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(2000); //设置动画持续时间
rotateAnim.setRepeatCount(3); //设置重复次数
rotateAnim.setFillAfter(false); //动画执行完后是否停留在执行完的状态rotateAnim.setStartOffset(0); //执行前的等待时间
mImgDog.startAnimation(rotateAnim);
方式二:xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotY="50%"
android:pivotX="50%"
android:duration="2000">
</rotate>
使用
RotateAnimation rotateAnim = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.anim_rotate_in);
mImgDog.startAnimation(rotateAnim);
AnimationSet
方式一:java代码
Animation alphaAnim = new AlphaAnimation(1, 0);
Animation scaleAnim = new ScaleAnimation(0f, 1, 0f, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
Animation rotateAnim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(alphaAnim);
animationSet.addAnimation(scaleAnim);
animationSet.addAnimation(rotateAnim);
animationSet.setDuration(2000); //设置动画持续时间
animationSet.setRepeatCount(3); //设置重复次数
animationSet.setFillAfter(false); //动画执行完后是否停留在执行完的状态
animationSet.setStartOffset(0); //执行前的等待时间
mImgDog.startAnimation(animationSet);
方式二:xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000">
</alpha>
<scale
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration = "2000"
android:fillAfter="true">
</scale>
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotY="50%"
android:pivotX="50%"
android:duration="2000">
</rotate>
</set>
使用
AnimationSet animationSet = (AnimationSet) AnimationUtils.loadAnimation(this, R.anim.anim_set);
mImgDog.startAnimation(animationSet);
插值器,Android自带的几种动画插值器:
java class | xml id | 效果 |
---|---|---|
AccelerateInterpolator | @android:anim/accelerate_interpolator | 加速,开始时慢中间加速 |
AccelerateDecelerateInterolator | @android:anim/accelerate_decelerate_interpolator | 先加速后减速,开始结束时慢,中间加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 反向,先向相反方向改变一段再加速播放 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值 |
BounceInterpolator | @android:anim/bounce_interpolator | 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100 |
CycleIinterpolator | @android:anim/bounce_interpolator | 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2* mCycles* Math.PI* input) |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 减速,开始时快然后减速 |
LinearInterpolator | @android:anim/decelerate_interpolator | 线性,线性均匀改变 |
OvershottInterpolator | @android:anim/overshoot_interpolator | 超越,最后超出目的值然后缓慢改变到目的值 |
下面详细介绍下几个平时最常用的属性和方法
android:duration
动画持续的时长,单位是毫秒
android:repeatCount
动画重复的次数,小于0无限循环播放
android:repeatMode
动画重复的Mode,reverse和restart
android:startOffset
动画播放延迟时长
android:fillAfter
动画结束之后是否保持动画的最终状态
android:fillBefore
动画结束之后是否保持动画开始前的状态
android:interpolator
动画插值器
1. AlphaAnimation
AlphaAnimation(float fromAlpha, float toAlpha)
float fromAlpha
动画起始时的透明度
float toAlpha
动画结束时的透明度
2. ScaleAnimation
ScaleAnimation(float fromX, float toX, float fromY, float toY,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
float fromX
动画起始时 X坐标上的伸缩尺寸
float toX
动画结束时 X坐标上的伸缩尺寸
float fromY
动画起始时Y坐标上的伸缩尺寸
float toY
动画结束时Y坐标上的伸缩尺寸
int pivotXType
动画在X轴相对于物件位置类型
float pivotXValue
动画相对于物件的X坐标的开始位置
int pivotYType
动画在Y轴相对于物件位置类型
float pivotYValue
动画相对于物件的Y坐标的开始位置
3. TranslateAnimation
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
float fromXDelta
动画开始的点离当前View X坐标上的差值
float toXDelta
动画结束的点离当前View X坐标上的差值
float fromYDelta
动画开始的点离当前View Y坐标上的差值
float toYDelta
动画开始的点离当前View Y坐标上的差值
4. RotateAnimation
RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
参数说明:
float fromDegrees
旋转的开始角度。
float toDegrees
旋转的结束角度。
int pivotXType
X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
float pivotXValue
X坐标的伸缩值。
int pivotYTypeY
轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
float pivotYValue
Y坐标的伸缩值。
接下来记录属性动画,未完待续….