动画第二步->ValueAnimator:自定义Interpolator

极客学院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函数大家还记得么?忘记的话,快快拾起数学吧,灰常重要~


动画第二步->ValueAnimator:自定义Interpolator_第1张图片
0.5*cos((input+1)*π)+0.5函数图像

该图是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值,通过函数图像绘制工具来绘制图像,看看变化速率,敲敲代码,感受感受

最后,不得不说,玩转数学函数,玩转插值器啊,有木有@~@

你可能感兴趣的:(动画第二步->ValueAnimator:自定义Interpolator)