Android动画之补间动画
Android常用的动画主要有逐帧动画、补间动画、属性动画以及Lottie等第三方动画库,而属性动画则是在Android3.0之后才提出的,因此今天我们首先来了解一下Android3.0之前常用的补间动画。
一、补间动画基础知识
补间,其实就是定义了开始帧和结束帧,然后由系统根据我们设定的值去计算中间的变化过程。怎么理解呢?举个例子,比如说位移动画,我们首先定义一个位移补间动画,new Translateanimation(0.0f,0.0f,10.0f,10.0f),这里定义位移的起点(0.0f,0.0f)和位移结束点(10.0f,10.0f),如果我们执行这个位移动画,就会发现实现了从起点到终点的是一个连续的位移变化,但是我们只是定义了开始和结束的点,而这个中间过程我们并没有定义,但是却有一个动画的过程,而这个动画过程就是由系统定义的。因此我们把这种由开发者定义开始和结束状态并由系统完成中间过程计算的动画称为补间动画。
理解了补间动画的定义后,接下来我们就正式开始学习补间动画。
常见的动画有位移动画TranslateAnimation、缩放动画ScaleAnimation、旋转动画RotateAnimation、透明动画AlphaAnimation四种,而他们都是继承了Animation类,所以首先我们来分析Animation。
1、Animation
Animation为抽象类,在抽象类中定义了通常的方法和参数
(1)通用方法和参数
参数类型
|
参数说明
|
/**
* Repeat the animation indefinitely.
*/
public static final int INFINITE = -1;
|
使用setRepeatCount(Animation.INFINITE)表示动画无限重复执行
|
/**
* When the animation reaches the end and the repeat count is INFINTE_REPEAT
* or a positive value, the animation restarts from the beginning.
*/
public static final int RESTART = 1;
|
在设置了前面的动画重复次数后,设置setRepeteMode(Animation.RESTART)表示每次动画结束重复执行时则从动画最开始位置再次执行到结束位置
|
/**
* When the animation reaches the end and the repeat count is INFINTE_REPEAT
* or a positive value, the animation plays backward (and then forward again).
*/
public static final int REVERSE = 2;
|
在设置了前面的动画重复次数后,设置setRepeteMode(Animation.REVERSE)表示每次动画结束重复执行时则从动画结束位置开始执行到最开始位置
|
public void setDuration(long durationMillis)
|
动画执行时间,单位ms
|
setFillAfter(boolean)
|
设置动画结束时保留动画结束时的状态
|
setFillBefore(boolean)
|
设置动画结束后回到初始状态
|
setFillEnable(boolean)
|
设置动画结束后回到初始状态
|
setInterpolator(boolean)
|
设置插画值,不手动设置的话,默认为AccelerateDecelerateInterpolator
即先匀加速后匀减速
|
setStartOffset(long)
|
即设置动画开始的延时,表示在调用该startAnimation()后long 时间后才开始真正执行动画
|
setZadjustment(int)
|
表示动画的内容在Z轴的位置,默认为normal
|
(2)监听器AnimationListener
public static interface AnimationListener {
/**
* Notifies the start of the animation.
*
* @param animation The started animation.
*/
void onAnimationStart(Animation animation);
/**
* Notifies the end of the animation. This callback is not invoked
* for animations with repeat count set to INFINITE.
*
* @param animation The animation which reached its end.
*/
void onAnimationEnd(Animation animation);
/**
* Notifies the repetition of the animation.
*
* @param animation The animation which was repeated.
*/
void onAnimationRepeat(Animation animation);
}
-
onAnimationStart() 在动画开始时回调此方法,重复执行动画时不会再调用
-
onAnimationEnd()在动画结束时回调此方法
-
onAnimationRepeat()在动画重复执行时调用,比如setRepeatCount(2),由于动画不设置重复则会执行1次,设置了重复后则为1+2=3次,而该方法只有在重复时才会调用,因此这里会调用调用两次。
监听器这里,我们后面会通过实例来说明。
2、AlphaAnimation透明动画
透明度动画主要是实现一个透明度的变化,其中0.0f表示完全透明,1.0f表示不透明
(1)构造方法:
/**
* Constructor to use when building an AlphaAnimation from code
*
* @param fromAlpha Starting alpha value for the animation, where 1.0 means
* fully opaque and 0.0 means fully transparent.
* @param toAlpha Ending alpha value for the animation.
*/
public AlphaAnimation(float fromAlpha, float toAlpha) {
mFromAlpha = fromAlpha;
mToAlpha = toAlpha;
}
(2)构造参数说明:
参数类型
|
参数说明
|
float fromAlpha
|
动画开始时的透明度
|
float toAlpha
|
动画结束时的透明度
|
(3)实例:
<1>代码实现
public void alpha(View view)
{
AlphaAnimation alpha = new AlphaAnimation(1.0f,0.0f);
alpha.setDuration(1000);
view.startAnimation(alpha);
}
<2>XML实现:(首先在res文件夹下创建anim目录,然后创建一个pop_anim.xml文件)
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="reverse"
android:shareInterpolator="true">
android:fromAlpha= "1.0"
android:toAlpha= "0.0"
android:duration= "1000" />
Animation animation = AnimationUtils.loadAnimation(this,R.anim.pop_anim);
v.startAnimation(animation);
(4)效果
2、ScaleAniamtion缩放动画
缩放动画主要是实现 X轴和Y轴方法上的对应比例scale的缩放,当然这里的缩放需要设置一个参照点(pivotX,pivotY),但是需要注意这里的参照点是相对于启动动画的view的而言,也就是说它的坐标并不是屏幕上的实际的的坐标。比如说,这里参照点为(0,0),那么是否就是屏幕左上角呢,并不是,这里的(0,0)实际上是view的左上角,而不是屏幕的左上角。这里需要明确,缩放、旋转中的参考点和平移中的参考起点和参考终点坐标都是相对于view而言的,一定要注意这一点。而我们在实际计算的时候,需要view的左上角坐标+参照点坐标。
即假设view左上角坐标为(x,y):
动画
|
参考点
|
参考起点
|
参考终点
|
实际坐标 |
缩放
|
(px,py)
|
无
|
无
|
(x+px,y+py)
|
旋转
|
(px,py)
|
无
|
无
|
(x+px,y+py)
|
平移
|
无
|
(fromX,fromY)
|
(toX,toY)
|
(x+fromX,y+fromY)
(x+toX,y+toY)
|
(1)构造方法:
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
/**
* Constructor to use when building a ScaleAnimation from code
*
* @param fromX Horizontal scaling factor to apply at the start of the
* animation
* @param toX Horizontal scaling factor to apply at the end of the animation
* @param fromY Vertical scaling factor to apply at the start of the
* animation
* @param toY Vertical scaling factor to apply at the end of the animation
* @param pivotXType Specifies how pivotXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotXValue The X coordinate of the point about which the object
* is being scaled, specified as an absolute number where 0 is the
* left edge. (This point remains fixed while the object changes
* size.) This value can either be an absolute number if pivotXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param pivotYType Specifies how pivotYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotYValue The Y coordinate of the point about which the object
* is being scaled, specified as an absolute number where 0 is the
* top edge. (This point remains fixed while the object changes
* size.) This value can either be an absolute number if pivotYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
(2)构造参数说明:
坐标类型
|
含义
|
float fromX,
|
表示动画开始时的相对于X轴缩放比例,1.0为原比例大小
|
float toX
|
表示动画结束时相对于X轴的缩放比例
|
float fromY
|
表示动画开始时相对于Y轴的缩放比例
|
float toY,
|
表示动画结束时相对于Y轴的缩放比例
|
float pivotX
|
参考点横坐标
|
, float pivotY
|
参考点纵坐标
|
可以看到这里有两个构造方法,第二个针对参考点,多了int pivotXType,int pivotYType两个参数,那么这两个参数的作用是什么?
pivotXType或者 pivotYType表示坐标的值的类型,设view的左上角坐标为(x,y),具体如下:
坐标类型
|
含义
|
ABSOLUTE
|
表示绝对数值,一般我们输入具体的坐标值,如(10f,100f),则表示相对于屏幕而言参考点坐标为*(x+10,y+100)
|
RELATIVE_TO_SELF
|
表示输入的值为view的宽或高的百分比,如(50%,50%),则表示相对于屏幕而言参考点为(x+view的宽*50%,y+view的高*50%)
|
RELATIVE_TO_PARENT
|
表示输入的值为view的父组件的宽或高的百分比,如(50%,50%),则表示相对于屏幕而言参考点为(x+view父组件的宽*50%,y+view父组件的高*50%)
|
(3)实例:
<1>代码实现
public void scale(View view)
{
ScaleAnimation scale = new ScaleAnimation(0.0f,1.0f,0.0f,1.0f,view.getWidth()/2,view.getHeight()/2);
// ScaleAnimation scale = new ScaleAnimation(1.0f,3.0f,0.0f,3.0f,0,0);
// scale.setFillAfter(true);
scale.setDuration(1000);
view.startAnimation(scale);
}
<2>XML实现
xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="reverse"
android:shareInterpolator="true">
android:fromXScale= "0.0"
android:toXScale= "1.0"
android:fromYScale= "0.0"
android:toYScale= "1.0"
android:pivotX= "50%"
android:pivotY= "50%"
android:duration= "3000" />
Animation animation = AnimationUtils.loadAnimation(this,R.anim.pop_anim);
v.startAnimation(animation);
(4)效果
现在针对上上面的例子做一点修改, ScaleAnimation scale = new ScaleAnimation(1.0f,3.0f,0.0f,3.0f,0,0);
效果如下:
这里我们取(0,0)坐标,会发现这里的(0,0)是指view的左上角,而不是整个屏幕坐标系。
3、RotateAnimation旋转动画
旋转动画是围绕我们动画的中心点从开始角度fromDegress到ToDegress。
(1)构造方法:
public RotateAnimation(float fromDegrees, float toDegrees) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotX = 0.0f;
mPivotY = 0.0f;
}
/**
* Constructor to use when building a RotateAnimation from code
*
* @param fromDegrees Rotation offset to apply at the start of the
* animation.
*
* @param toDegrees Rotation offset to apply at the end of the animation.
*
* @param pivotX The X coordinate of the point about which the object is
* being rotated, specified as an absolute number where 0 is the left
* edge.
* @param pivotY The Y coordinate of the point about which the object is
* being rotated, specified as an absolute number where 0 is the top
* edge.
*/
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
/**
* Constructor to use when building a RotateAnimation from code
*
* @param fromDegrees Rotation offset to apply at the start of the
* animation.
*
* @param toDegrees Rotation offset to apply at the end of the animation.
*
* @param pivotXType Specifies how pivotXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotXValue The X coordinate of the point about which the object
* is being rotated, specified as an absolute number where 0 is the
* left edge. This value can either be an absolute number if
* pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
* otherwise.
* @param pivotYType Specifies how pivotYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param pivotYValue The Y coordinate of the point about which the object
* is being rotated, specified as an absolute number where 0 is the
* top edge. This value can either be an absolute number if
* pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
* otherwise.
*/
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
(2)构造方法参数说明:
坐标类型
|
含义
|
float fromDegrees
|
表示动画开始时的旋转角度,正数顺时针,负数逆时针
|
float toDegrees
|
表示动画结束时的旋转角度
|
float pivotX
|
参考点横坐标
|
float pivotY
|
参考点纵坐标
|
(3)实例:
<1>代码实现
public void rotate(View view)
{
RotateAnimation rotate = new RotateAnimation(0f,-360f,view.getWidth()/2,view.getHeight()/2);
rotate.setDuration(1000);
rotate.setRepeatCount(Animation.INFINITE);
rotate.setRepeatMode(Animation.REVERSE);
view.startAnimation(rotate);
}
<2>XML实现
xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="reverse"
android:shareInterpolator="true">
android:fromDegrees= "0"
android:toDegrees= "-360"
android:pivotX= "50%"
android:pivotY= "50%"
android:duration= "1000"/>
(4)效果:
(1)构造方法:
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
mFromXValue = fromXDelta;
mToXValue = toXDelta;
mFromYValue = fromYDelta;
mToYValue = toYDelta;
mFromXType = ABSOLUTE;
mToXType = ABSOLUTE;
mFromYType = ABSOLUTE;
mToYType = ABSOLUTE;
}
/**
* Constructor to use when building a TranslateAnimation from code
*
* @param fromXType Specifies how fromXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromXValue Change in X coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toXType Specifies how toXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toXValue Change in X coordinate to apply at the end of the
* animation. This value can either be an absolute number if toXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param fromYType Specifies how fromYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromYValue Change in Y coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toYType Specifies how toYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toYValue Change in Y coordinate to apply at the end of the
* animation. This value can either be an absolute number if toYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
*/
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue) {
mFromXValue = fromXValue;
mToXValue = toXValue;
mFromYValue = fromYValue;
mToYValue = toYValue;
mFromXType = fromXType;
mToXType = toXType;
mFromYType = fromYType;
mToYType = toYType;
}
坐标类型
|
含义
|
float fromXValue
|
参考起点横坐标
|
float toXValue
|
参考终点横坐标
|
float fromYValue
|
参考起点纵坐标
|
float toYValue
|
参考终点纵坐标
|
(3)实例:
<1>代码实现
public void rotate(View view)
{
RotateAnimation rotate = new RotateAnimation(0f,-360f,view.getWidth()/2,view.getHeight()/2);
rotate.setDuration(1000);
rotate.setRepeatCount(Animation.INFINITE);
rotate.setRepeatMode(Animation.REVERSE);
view.startAnimation(rotate);
}
<2>XML实现
xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="reverse"
android:shareInterpolator="true">
android:fromDegrees= "0"
android:toDegrees= "-360"
android:pivotX= "50%"
android:pivotY= "50%"
android:duration= "1000"/>
有时候我们需要把多种动画效果放在一起来呈现,此时就需要使用年动画集合。
public void set(View view)
{
AnimationSet set = new AnimationSet(this,null);
AlphaAnimation alpha = new AlphaAnimation(0.0f,1.0f);
alpha.setDuration(1000);
RotateAnimation rotate = new RotateAnimation(0f,-360f,view.getWidth()/2,view.getHeight()/2);
rotate.setDuration(1000);
set.addAnimation(alpha);
set.addAnimation(rotate);
view.startAnimation(set);
}
其实很简单,只要把定义好的动画依次add到set中去就可以了。