动画分类
Animation 作用于 View 的动画
Transition 转场动画,一般用于 Activity 跳转时的过度动画
本文主要讲讲 Animation 的分类及各种使用方式
Animation
类别上可以分为 2 种
View Animation —— 动画仅仅用于展示,无法真正改变位置
Property Animation —— 动画可以真正改变位置
区别这2种动画最明显的就是点击事件,请看下图


使用方法上又分为以下这几种
FrameAnimation -> View Animation
TweenAnimation -> View Animation
ViewPropertyAnimator -> Property Animation
ObjectAnimator -> Property Animation
ValueAnimator -> Property Animation
上面就是大体的分类,可以先看看,大概有个轮廓。
接下来的是使用方法及效果展示
1. FrameAnimation (帧动画,逐帧显示)

xml 创建,资源文件放在 res/drawable 文件夹下
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<!-- oneshot 是否只执行一次 true 仅播放一次 false 循环播放 默认为 false -->
<!-- 每个 item 代表一帧,按顺序展示
drawable 显示的图片
duration 显示的时间,以毫秒计算 -->
<item
android:drawable="@drawable/frame1"
android:duration="1000" />
<item
android:drawable="@drawable/frame2"
android:duration="1000" />
<item
android:drawable="@drawable/frame3"
android:duration="1000" />
</animation-list>
通过资源文件,创建 AnimationDrawable 后使用
// 创建 AnimationDrawable
AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_frame);
// 将 animationDrawable 动画设置给 view
view.setBackgroundDrawable(animationDrawable);
// 启动动画
animationDrawable.start();
// 循环播放时,可以用此方法停止动画
animationDrawable.stop();
代码方式创建
// 创建 AnimationDrawable
AnimationDrawable animationDrawable = new AnimationDrawable();
// addFrame(Drawable,duration) 添加帧
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame1), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame2), 1000);
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame3), 1000);
// 是否只执行一次 true 仅播放一次 false 循环播放 默认为 false
animationDrawable.setOneShot(true);
// 将 animationDrawable 动画设置给 view
view.setBackgroundDrawable(animationDrawable);
//启动动画
animationDrawable.start();
2.TweenAnimation (补间动画)
包含 alpha(透明)、scale(缩放)、translate(位移)、rotate(旋转) 四种动画类型

xml 创建,资源放在 res/anim 文件夹下
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:repeatMode="restart">
<!-- duration 动画市场,毫秒计算
repeatMode 重复播放时的执行顺序 restart 从头开始 reverse 倒序-->
<!-- 位移动画 0~任意数
fromXDelta x 坐标起始点
toXDelta x 坐标结束点
fromYDelta y 坐标起始点
toYDelta y 坐标结束点 -->
<translate
android:fromXDelta="100"
android:fromYDelta="300"
android:toXDelta="200"
android:toYDelta="200" />
<!-- 旋转动画 值 -~360
fromDegrees 起始角度
toDegrees 结束角度
pivotX x 轴中心点
pivotY y 轴中心点 -->
<rotate
android:fromDegrees="60"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
<!-- 缩放动画 值 0.0~1.0
fromXScale x 轴起始缩放
toXScale x 轴结束缩放
fromYScale y 轴起始缩放
toYScale y 轴结束缩放
pivotX x 轴中心点
pivotY y 轴中心点 -->
<scale
android:fromXScale="0.5"
android:fromYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" />
<!-- 透明动画 值 0.0~1.0
fromAlpha 起始透明度
toAlpha 结束透明度 -->
<alpha
android:fromAlpha="0.6"
android:toAlpha="1" />
</set>
通过 AnimationUtils.loadAnimation 加载资源文件,设置动画
// 通过 AnimationUtils.loadAnimation 加载资源
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_tween);
//设置动画执行时间
animation.setDuration(1000);
//设置重复次数 -1 一直重复 次数>0 则重复几次 默认 为0 不管用
animation.setRepeatCount(-1);
// 重复模式 RESTART 从头开始 REVERSE 倒序开始 不管用
// animation.setRepeatMode(Animation.RESTART);
// 设置执行完动画后是使用转换过后的样式 true 是 使用 false 否 恢复到之前的样式 默认 false
// animation.setFillAfter(true);
//执行动画
view.startAnimation(animation);
代码方式创建
AnimationSet animationSet = new AnimationSet(true);
//位移动画
Animation translateAnimation = new TranslateAnimation(100, 200, 100, 200);
//旋转动画
Animation rotateAnimation = new RotateAnimation(60, 360);
//缩放动画
Animation scaleAnimation = new ScaleAnimation(0.5f, 1, 0.5f, 1);
//透明动画
Animation alphaAnimation = new AlphaAnimation(0.5f, 1.0f);
//添加动画
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
//设置动画执行时间
animationSet.setDuration(2000);
//执行动画
view.startAnimation(animationSet);
需要注意的一些东西
setRepeatCount(重复次数)、setRepeatMode(重复模式) 这两个方法对一组动画设置是无效的,google 是这么设计的,如果想要使用,只能对每个动画单独设置,例如
//位移动画
Animation translateAnimation = new TranslateAnimation(100, 200, 100, 200);
translateAnimation.(-1);
//旋转动画
Animation rotateAnimation = new RotateAnimation(60, 360);
rotateAnimation.(-1);
//缩放动画
Animation scaleAnimation = new ScaleAnimation(0.5f, 1, 0.5f, 1);
scaleAnimation.(-1);
//透明动画
Animation alphaAnimation = new AlphaAnimation(0.5f, 1.0f);
alphaAnimation.(-1);
setFillAfter(true) 动画结束后是否使用转换过后的样式 true 使用 false 否 恢复到之前的样式 默认值 false
3.ViewPropertyAnimator(属性动画-最简单的使用方式)

//得到 ViewPropertyAnimator,设置各种动画
ViewPropertyAnimator viewPropertyAnimator = view.animate();
//透明度
viewPropertyAnimator.alpha(0.5f)
//x 轴缩放
.scaleX(0.5f)
//y 轴缩放
.scaleY(0.5f)
//x 轴移动距离
.translationX(100)
//y 轴移动距离
.translationY(300)
//x 轴旋转角度
.rotationX(180)
//y 轴旋转角度
.rotationY(180)
//动画时间
.setDuration(2000)
.start();
方法使用上有点区别
xxx() 代表目标值,如 alpha(0.1f) 将透明度设置为 0.1
xxxBy() 代表在原有的基础上改变,如 alphaBy(0.1f) ,将透明度加 0.1
属性动画需要满足以下条件才可使用
- 被操作的属性要存在
- 属性需要创建对应的 set()、get() 方法
4.ObjectAnimator(属性动画-简单的使用方式)
效果的话跟 ViewPropertyAnimator 一样

ObjectAnimator 的使用
使用 ObjectAnimator.ofxxx(Object target, String propertyName, float... values) 创建 ObjectAnimator 对象
target 作用的对象,即要使用动画的 view
propertyName 属性名称
values 动画变化的值,可输入多个值,1个长度代表动画结束的值;2个长度的话第一个为初始值,第二个为结束值;大于2个长度,则第一个到最后一个之间的值为过渡值。
在这可能会有个疑问,1个长度的时候初始值从哪来?初始值会从属性的 get() 方法获取
xxx 代表属性的类型,如 alpha 是 Float,则使用 ofFloat,一般情况下使用 ofInt()、ofFloat() 足矣,如果是自定义的类型,使用 ofObject()
使用 AnimatorSet 执行一组动画
//动画集合
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.5f);
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0.5f);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 0.5f);
ObjectAnimator translationXAnimator = ObjectAnimator.ofFloat(view, "translationX", 100);
ObjectAnimator translationYAnimator = ObjectAnimator.ofFloat(view, "translationY", 300);
ObjectAnimator rotationXAnimator = ObjectAnimator.ofFloat(view, "rotationX", 180);
ObjectAnimator rotationYAnimator = ObjectAnimator.ofFloat(view, "rotationY", 180);
//组合动画顺序 play 当前需要执行的动画
animatorSet.play(scaleXAnimator)
//with 同时执行的动画
.with(scaleYAnimator)
.with(translationXAnimator)
.with(translationYAnimator)
//before 当前动画结束后需要执行的动画
.before(alphaAnimator)
//after 当前动画执行前需要执行的动画
.after(rotationXAnimator)
.after(rotationYAnimator);
//设置动画同时执行
// animatorSet.playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator, translationXAnimator,
// translationYAnimator, rotationXAnimator, rotationYAnimator);
//设置动画按顺序执行
// animatorSet.playSequentially(alphaAnimator, scaleXAnimator, scaleYAnimator, translationXAnimator,
// translationYAnimator, rotationXAnimator, rotationYAnimator);
//设置动画延时
// animatorSet.setStartDelay(2000);
//设置动画时间
animatorSet.setDuration(2000);
//启动动画
animatorSet.start();
5. ValueAnimator (属性动画-复杂的使用方式)
ValueAnimator 使用上会有些麻烦,需要自己监听动画,设置对应的变化,这种的自由度高一些,自己想怎么整就怎么整
ValueAnimator 的使用
使用 ValueAnimator.ofxxx() 创建 ValueAnimator 对象,通过 addUpdateListener() 方法监听值的变化,设置对应的动作
例如
// 创建 ValueAnimator 值的区间为 0~1
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1.0f);
// 设置动画时间
valueAnimator.setDuration(3000);
// 动画监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 得到动画值
float alphaValue = (Float) animation.getAnimatedValue();
// 将值设置给需要的 view
view.setAlpha(alphaValue);
}
});
// 启动动画
valueAnimator.start();
如何监听动画的开始、结束、变化?
有几种监听方式,AnimationListener、AnimatorPauseListener、addUpdateListener
监听事件中通过 animation.getAnimatedValue() 获取动画值
AnimationListener 监听动画的开始、结束、重复
new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// 动画启动的时候
}
@Override
public void onAnimationEnd(Animation animation) {
//动画结束的时候
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复的时候
}
}
AnimatorPauseListener 监听动画暂停、恢复
new AnimatorPauseListener() {
@Override
public void onAnimationPause(Animator animation) {
}
@Override
public void onAnimationResume(Animator animation) {
}
}
AnimatorUpdateListener 监听动画值变化
new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画值变化的时候
}
}
FrameAnimation 没有监听的方式
TweenAnimation 使用 setAnimationListener()
ViewPropertyAnimation 使用 setListener() 、setUpdateListener()
ObjectAnimator 使用 addListener()、addPauseListener()、addUpdateListener()
ValueAnimator 使用 addListener()、addPauseListener()、addUpdateListener()
属性动画比较重要的两个辅助类
1.Interpolator(速度变化器)
如果你想控制动画速度就用它,下面是几个常用的变化器
LinearInterpolator—— 线性插值器、恒定变化
AccelerateDecelerateInterpolator—— 先加速再减速
AccelerateInterpolator—— 先慢后快
DecelerateInterpolator—— 先快后慢
AnticipateInterpolator—— 先回滚然后一直加速
BounceInterpolator—— 到达结束点后会产生弹跳的效果
2.TypeEvaluator(类型估值器)
什么样的类型用什么样的类型估值器,这的类型就是动画参数的类型,下面是几个常用的估值器,如果是自定义的类型,那么就需要自己定义了
IntEvaluator int 类型
FloatEvaluator float 类型
ArgbEvaluator argb 类型,一般用于颜色变化时使用
下面是 Interpolator 和 TypeEvaluator 使用时的参考链接,有想了解的可以戳戳看~
Interpolator 的具体效果及详细使用可以看看下面的链接
HenCoder Android 自定义 View 1-6:属性动画 Property Animation(上手篇)
TypeEvaluator 的具体效果及详细使用可以看看下面的链接
HenCoder Android 自定义 View 1-7:属性动画 Property Animation(进阶篇)
