极客学院Animation教程讲解的很详细,点击进入哦
这里为学习的整理和补充O(∩_∩)O
前言
第一次学习的时候,没有记笔记,也没有敲代码,结果再继续学习高级进阶内容时,整个人懵逼了~~~(>_<)~~,so,良心建议大家都敲一敲代码,这里精简并丰富了极客学院的教程,大家一起进步
1、使用插值器,又名加速器
valueAnimator.setInterpolator(new BounceInterpolator());
一行代码就搞定啦,下边才是重点@~@
2、自定义插值器
直接代码O(∩_∩)O
public class MyInterploator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
return 1-input;
}
}
然后调用该代码:
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 400);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int) animation.getAnimatedValue();
view.layout(curValue, curValue, curValue + view.getWidth(), curValue + view.getHeight());
}});
valueAnimator.setInterpolator(new MyInterpolator());
valueAnimator.start();
会发现view从400->0的方向移动。那么WHY?下面细细道来~
-
首先看一下源码中的解释:
/**
A time interpolator defines the rate of change of an animation.
This allows animations to have non-linear motion, such as acceleration and deceleration.
*/
public interface TimeInterpolator {
/**
Maps a value representing the elapsed fraction of an animation to a value that represents
* the interpolated fraction. This interpolated value is then multiplied by the change in
* value of an animation to derive the animated value at the current elapsed animation time.
*
* @param input A value between 0 and 1.0 indicating our current point in the animation where 0 represents the start and 1.0 represents the end
* @return The interpolation value. This value can be more than 1.0 for interpolators which overshoot their targets, or less than 0 for interpolators that undershoot their targets.
*/
float getInterpolation(float input);
}
中文大意是说:
input参数:
代表理论上当前动画的进度,取值范围是[0,1],0表示开始,1表示结束,从0匀速增加到1.
egg: 在上述代码中,设置从0—>400,用时3000ms,那么在300ms的时候,input=300/3000=0.1,此时动画本应该在的位置=0+(400-0)*0.1=40。(表达式是:位置=开始值+(结束值-开始值)*进度)返回值:
代表当前动画实际想要的进度,大于1,超过目标值,小于1,小于开始值。
egg: 在上述代码中,我们返回值为1-input,这意味着动画实际位置=0+(400-0)*(1-0.1)=360;因此,我们看到动画是从400->0运动的。
假如返回值为1.5的时候,动画的实际位置=0+(400-0)*1.5=600,代入表达式,以此类推~
所以,我们只要通过input参数,改变返回值,即控制动画实际的进度。切记,input的值一直是匀速增加的,300ms是0.1,600ms是0.2,不会因为返回值而改变的哦
如果有点懵逼的话,那么我们根据AccelerateDecelerateInterpolator实际感受一下<( ̄︶ ̄)↗[GO!]
-
AccelerateDecelerateInterpolator(先加速后减速)解析
首先上源码⬇️
/**
* An interpolator where the rate of change starts and ends slowly but accelerates through the middle.
*/
public class AccelerateDecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
public AccelerateDecelerateInterpolator() {
}
@SuppressWarnings({"UnusedDeclaration"})
public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
}}
我们主要看这里:
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
//翻译为数学表达式就是:0.5\*cos((input+1)\*π)+0.5
}
不知道cos函数大家还记得么?忘记的话,快快拾起数学吧,灰常重要~
该图是0.5*cos((input+1)*π)+0.5的函数图像,input取值0->1,可以看出:如果input为0的时候,返回值为0,input为0.5的时候,返回值为0.5。根据函数变化图,可以看出返回值先由慢到快增长,然后有增长速率又变慢的过程,这也是动画变化的过程哦。
这里我只讲解这一个插值器,如果有需要,可以进入https://gold.xitu.io/entry/56f9e9a839b05700540ff6e7
该网址讲解了多个插值器滴
后记
如果仍有疑惑的话,就自己多去试试吧,把input(理想进度)作为X值,返回值(实际进度)作为Y值,通过函数图像绘制工具来绘制图像,看看变化速率,敲敲代码,感受感受
最后,不得不说,玩转数学函数,玩转插值器啊,有木有@~@