补间动画就是对View对象的内容执行一系列简单的转换(位置、大小、旋转和透明度)。
View Animation
根据不同的效果,补间动画共分为四类:
平移动画(Translate)
缩放动画(scale)
旋转动画(rotate)
透明度动画(alpha)
分类 | 原理 | 对应Animation子类 |
---|---|---|
平移动画(Translate) | 移动视图的位置 | TranslateAnimation |
缩放动画(scale) | 放大/缩小视图的大小 | ScaleAnimation |
旋转动画(rotate) | 旋转视图的角度 | RotateAnimation |
透明度动画(alpha) | 改变视图的透明度 | AlphaAnimation |
Animation是AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation这些类的父类。
xml属性 | 作用 |
---|---|
android:detachWallpaper | 动画是否在壁纸上运行 |
android:duration | 动画运行的时间(以毫秒为单位) |
android:fillAfter | 动画结束时是否保持动画最后的状态 |
android:fillBefore | 动画结束时是否还原到开始动画前的状态 |
android:fillEnabled | 与android:fillBefore效果相同 |
android:interpolator | 设定插值器 |
android:repeatCount | 动画重复次数 |
android:repeatMode | reverse表示倒序回放,restart表示从头播放 |
android:startOffset | 动画运行前的延迟(毫秒) |
android:zAdjustment | 被设置动画的内容运行时在Z轴上的位置(top/bottom/normal) |
常量 | 作用 |
---|---|
ABSOLUTE | 指定的维度是像素的绝对数目 |
INFINITE | 无限重复动画 |
RELATIVE_TO_PARENT | 指定的维度持有浮点数,并应乘以被动画对象的父级的高度或宽度。 |
RELATIVE_TO_SELF | 指定的维度持有浮点数,并应乘以动画对象自身的高度或宽度 |
RESTART | 从头播放 |
REVERSE | 倒序回放 |
START_ON_FIRST_FRAME | 可以用作开始时间,以指示开始时间应该是当前时间getTransformation(long, Transformation)对于第一个动画帧调用。 |
ZORDER_BOTTOM | |
ZORDER_NORMAL | 将被动画的内容按当前Z顺序保存 |
ZORDER_TOP | 在动画期间强制将动画内容置于所有其他内容之上 |
AlphaAnimation(float fromAlpha, float toAlpha)
android:fromAlpha:动画开始的透明度
android:toAlpha:动画结束的透明度
RotateAnimation(float fromDegrees, float toDegrees)
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
android:fromDegrees:旋转开始角度,正代表顺时针度数,负代表逆时针度数
android:toDegrees:旋转结束角度,正代表顺时针度数,负代表逆时针度数
android:pivotX:旋转轴点的x坐标
android:pivotY:旋转轴点的y坐标
pivotX pivotY,可取值为数字,百分比,或者百分比p
设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
ScaleAnimation(float fromX, float toX, float fromY, float toY)
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
TranslateAnimation(int fromXType, float fromXDelta, int toXType, float toXDelta, int fromYType, float fromYDelta, int toYType, float toYDelta)
AnimationSet表示应该一起播放的一组动画。每个独立动画的转换被组合成一个单一的转换。如果动画集设置了它的子集合也设置的任何属性(例如,持续时间或之前的填充),则动画集的值将覆盖子值。
duration, repeatMode, fillBefore, fillAfter: These properties, when set on an AnimationSet object, will be pushed down to all child animations.(当设置在一个动画集对象,将向下推到所有的子动画)
repeatCount, fillEnabled: These properties are ignored for AnimationSet.(这些属性被忽略)
startOffset, shareInterpolator: These properties apply to the AnimationSet itself.(这些属性适用于动画集本身)
在代码中使用的步骤基本是类似的:
1.创建一个AnimationSet对象(Animation子类);
2.增加需要创建相应的Animation对象;
3.增加项目的需求,为Animation对象设置相应的数据;
4.将Animatin对象添加到AnimationSet对象当中;
5.使用控件对象开始执行AnimationSet。
AnimationSet animationSet = new AnimationSet(true);
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT,0f,
Animation.RELATIVE_TO_PARENT,0.5f,
Animation.RELATIVE_TO_PARENT,0f,
Animation.RELATIVE_TO_PARENT,0.5f
);
translateAnimation.setDuration(2000);
animationSet.addAnimation(translateAnimation);
animationSet.setFillAfter(true);
ivAnim.startAnimation(animationSet);
1.在res/anim的文件夹里创建动画效果.xml文件
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:repeatCount="0"
android:repeatMode="restart"
android:startOffset="1000"
android:zAdjustment="bottom"
android:fromXDelta="0"
android:toXDelta="50%p"
android:fromYDelta="0"
android:toYDelta="30%p"
>
translate>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillBefore="false">
<alpha
android:fromAlpha="1"
android:toAlpha="0"
android:duration="3000"/>
set>
2.代码创建Animation对象,开始动画
Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate_demo1);
ivAnim.startAnimation(animation);
xml方式:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="0.6"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
<set android:interpolator="@android:anim/decelerate_interpolator">
<scale
android:fromXScale="1.4"
android:toXScale="0.0"
android:fromYScale="0.6"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400"
android:fillBefore="false" />
<rotate
android:fromDegrees="0"
android:toDegrees="-45"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="700"
android:duration="400" />
set>
set>
代码实现方式:
AnimationSet setAnimation = new AnimationSet(true);
// 步骤1:创建组合动画对象(设置为true)
// 步骤2:设置组合动画的属性
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);
// 步骤3:逐个创建子动画
// 子动画1:旋转动画
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 子动画2:平移动画
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 子动画3:透明度动画
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 子动画4:缩放动画
Animation scale = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale.setDuration(1000);
scale.setStartOffset(4000);
// 步骤4:将创建的子动画添加到组合动画里
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale);
ivAnim.startAnimation(setAnimation);
Animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
参考Android动画系列之插值器(Interpolator)和估值器(TypeEvaluator)详解
Github示例代码