Android中的动画之属性动画
属性动画
属性动画提供了两个类
* ViewPropertyAnimator
* ObjectAnimator
区别:
* ViewPropertyAnimator 只能操作他给我们提供的属性。而 ObjectAnimator 可以自己定制属性;
* ViewPropertyAnimator 使用简单,而 ObjectAnimator 的使用并不简单;
*
ViewPropertyAnimator
使用方法
ViewPropertyAnimator anim = mImageView.animate();
anim.translationX(100);
anim.translationY(100);
anim.translationZ(100);
anim.rotation(100);
anim.rotationX(100);
anim.rotationY(100);
anim.scaleX(100);
anim.scaleY(100);
anim.alpha(1);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(500);
链式调用:
mImageView.animate()
.translationX(100)
.translationY(100)
.translationZ(100)
.rotation(100)
.rotationX(100)
.rotationY(100)
.scaleX(100)
.scaleY(100)
.alpha(1)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setDuration(500);
ObjectAnimator
构造方法
* ObjectAnimator.ofFloat();
* ObjectAnimator.ofInt();
* ObjectAnimator.ofArgb();
* ObjectAnimator.ofObject();
* ObjectAnimator.ofMultiFloat();
* ObjectAnimator.ofMultiInt();
* ObjectAnimator.ofPropertyValuesHolder();
构造参数说明
* ObjectAnimator anim = ObjectAnimator.ofFloat(目标view, 属性名, 目标值);
* ObjectAnimator anim = ObjectAnimator.ofFloat(目标view, 属性名, 起始值, 目标值);
* ObjectAnimator anim = ObjectAnimator.ofFloat(目标view, 属性名, 起始值, 转接值, 转接值, 目标值);
用法1
ObjectAnimator anim = ObjectAnimator.ofXXX();
anim.start();
用法2:自定义view
setProgress(float vlue){
this.
}
float getProgress();
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "progress", 50);
anim.start();
举例:让img向右平移400
ObjectAnimator anim = ObjectAnimator.ofFloat(mImageView, "translationX", 400);
anim.start();
举例:从一个颜色值变到另外一个颜色值
ObjectAnimator anim = ObjectAnimator.ofInt(mView, "color", 0xffff0000, 0xff00ff00);
anim.setEvaluator(new ArgbEvaluator());
anim.start();
知识拓展:
Evaluator 的内容看这里:https://juejin.cn/post/7218916720332161082
属性动画 - 监听器
给动画设置监听器,可以在关键时刻得到反馈,从而及时做出合适的操作,例如在动画的属性更新时同步更新其他数据,或者在动画结束后回收资源等。
ViewPropertyAnimator 的监听器
1.设置监听器:
* setListener(AnimatorListener anim);
* setUpdateListener(AnimatorUpdateListener anim);
2.移除监听器:
* setListener(null);
* setUpdateListener(null);
ObjectAnimator 的监听器
1.设置监听器:
* addListener(AnimatorListener anim);
* addUpdateListener(AnimatorUpdateListener anim);
2.移除监听器:
* removeListener();
* removeUpdateListener();
注意:
1.由于 ObjectAnimator 支持使用 pause() 方法暂停,所以它还多了暂停监听的支持;
* addPauseListener();
* removePauseListener();
2.ViewPropertyAnimator 可以设置一次性的动画开始或结束的监听。
* withStartAction();
* withEndAction();
AnimatorListener 类介绍:共有 4 个回调方法
1.onAnimationStart(Animator animation);
2.onAnimationEnd(Animator animation);
3.onAnimationCancel(Animator animation);
* 需要说明一下的是,就算动画被取消,`onAnimationEnd()` 也会被调用。
* 所以当动画被取消时,如果设置了 AnimatorListener ,那么 onAnimationCancel() 和 onAnimationEnd() 都会被调用。
* onAnimationCancel() 会先于 onAnimationEnd() 被调用。
4.onAnimationRepeat(Animator animation);
* 由于 `ViewPropertyAnimator` 不支持重复,所以这个方法对 `ViewPropertyAnimator` 相当于无效。
AnimatorUpdateListener 类介绍:就一个方法
* onAnimationUpdate(ValueAnimator animation);
* 方法的参数是一个 `ValueAnimator`,`ValueAnimator` 是 `ObjectAnimator` 的父类,也是 `ViewPropertyAnimator` 的内部实现,所以这个参数其实就是 `ViewPropertyAnimator` 内部的那个 `ValueAnimator`,或者对于 `ObjectAnimator` 来说就是它自己本身。
* `ValueAnimator` 有很多方法可以用,它可以查看当前的动画完成度、当前的属性值等等。
插值器 Interpolator
系统提供的插值器:
1.AccelerateDecelerateInterpolator();// 默认,先加速再减速(从速度为 0 开始逐渐加速,然后再逐渐减速直到 0)
2.LinearInterpolator();// 匀速,线性
3.AnticipateOvershootInterpolator();// 带施法前摇和回弹
4.AccelerateInterpolator();// 持续加速(在整个动画过程中,一直在加速,直到动画结束的一瞬间,直接停止)
5.DecelerateInterpolator();// 持续减速直到0(动画开始的时候是最高速度,然后在动画过程中逐渐减速,直到动画结束的时候恰好减速到 0)
6.AnticipateInterpolator();// 先回拉一下再进行正常动画轨迹(蓄力效果)
7.OvershootInterpolator();// 动画会超过目标值一些,然后再弹回来(效果看起来有点像你一屁股坐在沙发上后又被弹起来一点的感觉)
8.AnticipateOvershootInterpolator();// 6和7的结合体(开始前回拉,最后超过一些然后回弹)
9.BounceInterpolator();// 在目标值处弹跳(有点像玻璃球掉在地板上的效果)
10.CycleInterpolator();// 这个也是一个正弦 / 余弦曲线,不过它和 `AccelerateDecelerateInterpolator` 的区别是,它可以自定义曲线的周期,所以动画可以不到终点就结束,也可以到达终点后回弹,回弹的次数由曲线的周期决定,曲线的周期由 `CycleInterpolator()` 构造方法的参数决定。
11.PathInterpolator();// 自定义动画完成度 / 时间完成度曲线。用这个 "Interpolator" 你可以定制出任何你想要的速度模型。定制的方式是使用一个 "Path" 对象来绘制出你要的动画完成度 / 时间完成度曲线。
除了上面的这些,Android 5.0 (API 21)引入了三个新的 `Interpolator` 模型,并把它们加入了 support v4 包中。这三个新的 `Interpolator` 每个都和之前的某个已有的 `Interpolator` 规则相似,只有略微的区别。
Android5.0(API 21)引入的三个 "Interpolator" 模型:
1.FastOutLinearInInterpolator();// 加速运动。
* 这个 `Interpolator` 的作用你不能看它的名字,一会儿 fast 一会儿 linear 的,完全看不懂。
* 其实它和 `AccelerateInterpolator` 一样,都是一个持续加速的运动路线。只不过 `FastOutLinearInInterpolator` 的曲线公式是用的贝塞尔曲线,而 `AccelerateInterpolator` 用的是指数曲线。
* 具体来说,它俩最主要的区别是 `FastOutLinearInInterpolator` 的初始阶段加速度比 `AccelerateInterpolator` 要快一些。
2.FastOutSlowInInterpolator();// 先加速再减速。
* 同样也是先加速再减速的还有前面说过的 `AccelerateDecelerateInterpolator`,不过它们的效果是明显不一样的。
* `FastOutSlowInInterpolator` 用的是贝塞尔曲线,`AccelerateDecelerateInterpolator` 用的是正弦 / 余弦曲线。
* 具体来讲, `FastOutSlowInInterpolator` 的前期加速度要快得多。
3.LinearOutSlowInInterpolator();// 持续减速。
* 它和 `DecelerateInterpolator` 比起来,同为减速曲线,主要区别在于 `LinearOutSlowInInterpolator` 的初始速度更高。
* 对于人眼的实际感觉,区别其实也不大,不过还是能看出来一些的。
---------------------------------------------------------------------------
------------------------- 插值器:PathInterpolator -------------------------
---------------------------------------------------------------------------
解释:
* 自定义动画完成度 / 时间完成度曲线。
* 用这个 "Interpolator" 你可以定制出任何你想要的速度模型。
* 定制的方式是使用一个 "Path" 对象来绘制出你要的动画完成度 / 时间完成度曲线。
例如:
案例1:匀速效果
Path interpolatorPath = new Path();
interpolatorPath.lineTo(1, 1);// 匀速
案例2:回弹效果
Path interpolatorPath = new Path();
// 先以「动画完成度 : 时间完成度 = 1 : 1」的速度匀速运行 25%
interpolatorPath.lineTo(0.25f, 0.25f);
// 然后瞬间跳跃到 150% 的动画完成度
interpolatorPath.moveTo(0.25f, 1.5f);
// 再匀速倒车,返回到目标点
interpolatorPath.lineTo(1, 1);
注意:
你根据需求,绘制出自己需要的 `Path`,就能定制出你要的速度模型。
不过要注意,这条 `Path` 描述的其实是一个 `y = f(x) (0 ≤ x ≤ 1)` (y 为动画完成度,x 为时间完成度)的曲线,所以同一段时间完成度上不能有两段不同的动画完成度(这个好理解吧?因为内容不能出现分身术呀),而且每一个时间完成度的点上都必须要有对应的动画完成度(因为内容不能在某段时间段内消失呀)。所以,下面这样的 `Path` 是非法的,会导致程序 FC:
程序FC的几种情况:
* 出现重复的动画完成度,即动画内容出现「分身」——程序 FC
* 有一段时间完成度没有对应的动画完成度,即动画出现「中断」——程序 FC