属性动画
1.ViewPropertyAnimator
使用方法view.animate().translationX(100);
。。。。。。
![](https://img.haomeiwen.com/i5876940/55e7018754ba5904.png)
View 的每个方法都对应了 ViewPropertyAnimator 的两个方法,其中一个是带有 -By 后缀的,例如,View.setTranslationX() 对应了 ViewPropertyAnimator.translationX() 和 ViewPropertyAnimator.translationXBy() 这两个方法。其中带有 -By() 后缀的是增量版本的方法,例如,translationX(100) 表示用动画把 View 的 translationX 值渐变为 100,而 translationXBy(100) 则表示用动画把 View 的 translationX 值渐变地增加 100。
2.ObjectAnimator
使用方式:
如果是自定义控件,需要添加 setter / getter 方法;
用 ObjectAnimator.ofXXX() 创建 ObjectAnimator 对象;
用 start() 方法执行动画。
例:
public class SportsView extends View {
float progress = 0;
......
// 创建 getter 方法
public float getProgress() {
return progress;
}
// 创建 setter 方法
public void setProgress(float progress) {
this.progress = progress;
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
......
canvas.drawArc(arcRectF, 135, progress * 2.7f, false, paint);
......
}
}
......
// 创建 ObjectAnimator 对象
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "progress", 0, 65);
// 执行动画
animator.start();
2.1 setDuration(int duration)设置动画时长 单位:毫秒
例:
// imageView1: 500 毫秒
imageView1.animate()
.translationX(500)
.setDuration(500);
// imageView2: 2 秒
ObjectAnimator animator = ObjectAnimator.ofFloat(
imageView2, "translationX", 500);
animator.setDuration(2000);
animator.start();
2.2 setInterpolator(Interpolator interpolator)设置Interpolator
Interpolator 是一个速度设置器,在参数中填入不同的Interpolator,动画就会以不同的速度模型来执行。
例:
// imageView1: 线性 Interpolator,匀速
imageView1.animate()
.translationX(500)
.setInterpolator(new LinearInterpolator());
// imageView: 带施法前摇和回弹的 Interpolator
ObjectAnimator animator = ObjectAnimator.ofFloat(
imageView2, "translationX", 500);
animator.setInterpolator(new AnticipateOvershootInterpolator());
animator.start();
2.2.1 AccelerateDeceleratelInterpolator 先加速再减速
先加速再减速。这是默认的 Interpolator,也就是说如果你不设置的话,那么动画将会使用这个 Interpolator。
这个是一种最符合现实中物体运动的 Interpolator,它的动画效果看起来就像是物体从速度为 0 开始逐渐加速,然后再逐渐减速直到 0 的运动。它的速度 / 时间曲线以及动画完成度 / 时间曲线都是一条正弦 / 余弦曲线(这句话看完就忘掉就行,没用)。
用途:就像上面说的,它是一种最符合物理世界的模型,所以如果你要做的是最简单的状态变化(位移、放缩、旋转等等),那么一般不用设置 Interpolator,就用这个默认的最好。
2.2.2 LinearInterpolator 匀速
2.2.3 AccelerateInterpolator 持续加速
在整个过程中,动画一直加速,一直持续到动画结束的一瞬间。
用途:它主要用在离场效果中,比如某个物体从界面中飞离,就可以用这种效果。它给人的感觉就会是「这货从零起步,加速飞走了」。到了最后动画骤停的时候,物体已经飞出用户视野,看不到了,所以他们是并不会察觉到这个骤停的。
2.2.4 DecelerateInterpolator 持续减速到0
动画开始的时候是最高速度,然后在动画中逐渐减速,直到动画结束的时候恰好减速到0。
用途:它的效果和上面这个 AccelerateInterpolator 相反,适用场景也和它相反:它主要用于入场效果,比如某个物体从界面的外部飞入界面后停在某处。它给人的感觉会是「咦飞进来个东西,让我仔细看看,哦原来是 XXX」。
2.2.5 AnticipateInterpolator 先拉回一下然后再进行正常动画轨迹。
效果看起来就是 投掷物体或者跳跃等动作前的蓄力。
2.2.6 OvershootInterpolator
2.2.7 AnticipateOvershootinterpolator
动画在开启前回拉,最后超过一些然后回弹。
2.2.8 BounceInterpolator
在目标值处弹跳!
2.2.9 CycleInterpolator
这个也是一个正弦 / 余弦曲线,不过它和 AccelerateDecelerateInterpolator 的区别是,它可以自定义曲线的周期,所以动画可以不到终点就结束,也可以到达终点后回弹,回弹的次数由曲线的周期决定,曲线的周期由 CycleInterpolator() 构造方法的参数决定。
2.2.10 PathInterpolator
自定义动画完成度/时间完成度曲线
用这个 Interpolator 你可以定制出任何你想要的速度模型。定制的方式是使用一个 Path 对象来绘制出你要的动画完成度 / 时间完成度曲线。例如:
Path interpolatorPath = new Path();
...
// 匀速
interpolatorPath.lineTo(1, 1);
![](https://img.haomeiwen.com/i5876940/ea46998971d0142e.png)
Path interpolatorPath = new Path();
...
// 先以「动画完成度 : 时间完成度 = 1 : 1」的速度匀速运行 25%
interpolatorPath.lineTo(0.25f, 0.25f);
// 然后瞬间跳跃到 150% 的动画完成度
interpolatorPath.moveTo(0.25f, 1.5f);
// 再匀速倒车,返回到目标点
interpolatorPath.lineTo(1, 1);
![](https://img.haomeiwen.com/i5876940/f1508c22af427021.png)
注意:
这条 Path 描述的其实是一个 y = f(x) (0 ≤ x ≤ 1) (y 为动画完成度,x 为时间完成度)的曲线,所以同一段时间完成度上不能有两段不同的动画完成度(这个好理解吧?因为内容不能出现分身术呀),而且每一个时间完成度的点上都必须要有对应的动画完成度(因为内容不能在某段时间段内消失呀)。所以,下面这样的 Path 是非法的,会导致程序 FC:
![](https://img.haomeiwen.com/i5876940/3196fb956984e785.png)
出现重复的动画完成度,即动画内容出现「分身」——程序 FC
![](https://img.haomeiwen.com/i5876940/0c8b6c1abe567b56.png)
有一段时间完成度没有对应的动画完成度,即动画出现「中断」——程序 FC
Android 5.0 (API 21)引入了三个新的 Interpolator 模型,并把它们加入了 support v4 包中。这三个新的 Interpolator 每个都和之前的某个已有的 Interpolator 规则相似。
2.2.11 FastOutLinearInInterpolator 加速运动
其实它和 AccelerateInterpolator 一样,都是一个持续加速的运动路线。只不过 FastOutLinearInInterpolator 的曲线公式是用的贝塞尔曲线,而 AccelerateInterpolator 用的是指数曲线。具体来说,它俩最主要的区别是 FastOutLinearInInterpolator 的初始阶段加速度比 AccelerateInterpolator 要快一些。
FastOutLinearInInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/b6f5f2de989c631a.png)
AccelerateInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/bc9bc0f28b4552e3.png)
合并
![](https://img.haomeiwen.com/i5876940/46ea89e10d11d0ac.png)
结论:开发中,想用哪个就用哪个
2.2.12 FastOutSlowInInterpolator 先加速再减速
同样也是先加速再减速的还有前面说过的 AccelerateDecelerateInterpolator,不过它们的效果是明显不一样的。FastOutSlowInInterpolator 用的是贝塞尔曲线,AccelerateDecelerateInterpolator 用的是正弦 / 余弦曲线。具体来讲, FastOutSlowInInterpolator 的前期加速度要快得多
FastOutSlowInInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/738877251f515b58.png)
AccelerateDecelerateInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/a3296d2559491813.png)
不论是从动图还是从曲线都可以看出,这二者比起来,FastOutSlowInInterpolator 的前期加速更猛一些,后期的减速过程的也减得更迅速。用更直观一点的表达就是,AccelerateDecelerateInterpolator 像是物体的自我移动,而 FastOutSlowInInterpolator 则看起来像有一股强大的外力「推」着它加速,在接近目标值之后又「拽」着它减速。总之,FastOutSlowInterpolator 看起来有一点「着急」的感觉。
速度曲线对比
![](https://img.haomeiwen.com/i5876940/17303e3feeacb732.png)
2.2.13 LinearOutSlowInInterpolator 持续减速
它和 DecelerateInterpolator 比起来,同为减速曲线,主要区别在于 LinearOutSlowInInterpolator 的初始速度更高。
LinearOutSlowInInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/593f70ad20684636.png)
DecelerateInterpolator 速度曲线
![](https://img.haomeiwen.com/i5876940/546c946d65d51bc9.png)
二者速度曲线比较
![](https://img.haomeiwen.com/i5876940/29c493e15996f91a.png)
2.3 设置监听器
给动画设置监听器,可以在关键时刻得到反馈,从而及时做出合适的操作,例如在动画的属性更新时同步更新其他数据,或者在动画结束后回收资源等。
设置监听器的方法, ViewPropertyAnimator 和 ObjectAnimator 略微不一样: ViewPropertyAnimator 用的是 setListener() 和 setUpdateListener() 方法,可以设置一个监听器,要移除监听器时通过 set[Update]Listener(null) 填 null 值来移除;
而 ObjectAnimator 则是用 addListener() 和 addUpdateListener() 来添加一个或多个监听器,移除监听器则是通过 remove[Update]Listener() 来指定移除对象。
另外,由于 ObjectAnimator 支持使用 pause() 方法暂停,所以它还多了一个 addPauseListener() / removePauseListener() 的支持;而 ViewPropertyAnimator 则独有 withStartAction() 和 withEndAction() 方法,可以设置一次性的动画开始或结束的监听。
3.1 ViewPropertyAnimator.setListener() / ObjectAnimator.addListener()
这两个方法的名称不一样,可以设置的监听器数量也不一样,但它们的参数类型都是 AnimatorListener,所以本质上其实都是一样的。 AnimatorListener 共有 4 个回调方法:
3.1.1 onAnimationStart(Animator animation)
当动画开始执行时,这个方法被调用。
3.1.2 onAnimationEnd(Animator animation)
当动画结束时,这个方法被调用。
3.1.3 onAnimationCancel(Animator animation)
当动画被通过 cancel() 方法取消时,这个方法被调用。
需要说明一下的是,就算动画被取消,onAnimationEnd() 也会被调用。所以当动画被取消时,如果设置了 AnimatorListener,那么 onAnimationCancel() 和 onAnimationEnd() 都会被调用。onAnimationCancel() 会先于 onAnimationEnd() 被调用。
3.1.4 onAnimationRepeat(Animator animation)
当动画通过 setRepeatMode() / setRepeatCount() 或 repeat() 方法重复执行时,这个方法被调用。
由于 ViewPropertyAnimator 不支持重复,所以这个方法对 ViewPropertyAnimator 相当于无效。
3.2 ViewPropertyAnimator.setUpdateListener() / ObjectAnimator.addUpdateListener()
和上面 3.1 的两个方法一样,这两个方法虽然名称和可设置的监听器数量不一样,但本质其实都一样的,它们的参数都是 AnimatorUpdateListener。它只有一个回调方法:onAnimationUpdate(ValueAnimator animation)。
3.2.1 onAnimationUpdate(ValueAnimator animation)
当动画的属性更新时(不严谨的说,即每过 10 毫秒,动画的完成度更新时),这个方法被调用。
方法的参数是一个 ValueAnimator,ValueAnimator 是 ObjectAnimator 的父类,也是 ViewPropertyAnimator 的内部实现,所以这个参数其实就是 ViewPropertyAnimator 内部的那个 ValueAnimator,或者对于 ObjectAnimator 来说就是它自己本身。
ValueAnimator 有很多方法可以用,它可以查看当前的动画完成度、当前的属性值等等。不过 ValueAnimator 是下一期才讲的内容,所以这期就不多说了。
3.3 ObjectAnimator.addPauseListener()
由于 ObjectAnimator.pause() 是下期的内容,所以这个方法在这期就不讲了。当然,如果你有兴趣的话,现在就了解一下也可以。
3.4 ViewPropertyAnimator.withStartAction/EndAction()
这两个方法是 ViewPropertyAnimator 的独有方法。它们和 set/addListener() 中回调的 onAnimationStart() / onAnimationEnd() 相比起来的不同主要有两点:
withStartAction() / withEndAction() 是一次性的,在动画执行结束后就自动弃掉了,就算之后再重用 ViewPropertyAnimator 来做别的动画,用它们设置的回调也不会再被调用。而 set/addListener() 所设置的 AnimatorListener 是持续有效的,当动画重复执行时,回调总会被调用。
withEndAction() 设置的回调只有在动画正常结束时才会被调用,而在动画被取消时不会被执行。这点和 AnimatorListener.onAnimationEnd() 的行为是不一致的。
网友评论