14

我想使用缓动功能的自定义在animationAndroid view(按钮)上应用翻译:interpolator

public static float easeOut(float t,float b , float c, float d) {
    if ((t/=d) < (1/2.75f)) {
       return c*(7.5625f*t*t) + b;
    } else if (t < (2/2.75f)) {
       return c*(7.5625f*(t-=(1.5f/2.75f))*t + .75f) + b;
    } else if (t < (2.5/2.75)) {
       return c*(7.5625f*(t-=(2.25f/2.75f))*t + .9375f) + b;
    } else {
       return c*(7.5625f*(t-=(2.625f/2.75f))*t + .984375f) + b;
    }
}

我有一个使用自定义插值器的示例,如下所示:

插值器是:

public class HesitateInterpolator implements Interpolator {
    public HesitateInterpolator() {
    }

    public float getInterpolation(float t) {
        float x = 2.0f * t - 1.0f;
        return 0.5f * (x * x * x + 1.0f);
    }
}

并像这样使用:

ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
anim.setInterpolator(new HesitateInterpolator());

我的问题是:这些值b, c,d是为了什么?

4

5 回答 5

23

仅供参考:对于只想要轻松插值器的人,您可以使用myAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

于 2016-05-11T15:44:55.420 回答
15

我做了一个可以解决这个问题的库。AndroidEasingFunctions

于 2014-08-07T14:19:45.517 回答
11

根据Robert Penner 的 Easing Functions ,如此所述:

t:当前时间,b:开始值,c:变化值,d:持续时间

如果你想实现你的自定义插值器,你必须做这样的事情:

(这将是 的实现easeInOutQuint

public class MVAccelerateDecelerateInterpolator implements Interpolator {

    // easeInOutQuint
    public float getInterpolation(float t) {
        float x;
        if (t<0.5f)
        { 
            x = t*2.0f;
            return 0.5f*x*x*x*x*x;
        }
        x = (t-0.5f)*2-1;
        return 0.5f*x*x*x*x*x+1;
    }
}

编辑:要实现缓动函数,您需要一些数学知识,考虑到该getInterpolation方法仅获取 t 参数,从 0.0 到 1.0。

所以基本上你需要开发y(t)函数,t从0到1,y值从0到1,如下图:

在此处输入图像描述

您更改的是从 0 到 1 的曲线(例如,在图像中,绿线是线性的)。您需要“规范化”缓动函数以保持在 (0, 1) x (0, 1) 正方形中,正如您在我的easeInOutQuint实现中看到的那样。

于 2014-04-11T14:59:07.937 回答
10

1,2,3 去

  1. 使用这个很棒的网站创建自定义三次贝塞尔曲线。并获得曲线的控制点。在 0,0 和 1,1 之间
  2. Interpolator customInterpolator = PathInterpolatorCompat.create(cpX1,cpX2,cpY1,cpY2)
  3. 将此 customInterpolator 添加到您的任何动画中。

添加了一个要点这里还有一些。

于 2016-08-24T14:21:32.433 回答
0

这是另一个解决方案,通过最近添加到 android 的支持库而成为可能: https ://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce

和一个正在使用的例子:

public static void expand(final View v) {
    v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    final int targetHeight = v.getMeasuredHeight();

    if ( v.getHeight() != targetHeight ) {
        // Older versions of android (pre API 21) cancel animations for views with a height of 0 so use 1 instead.
        v.getLayoutParams().height = 1;
        v.setVisibility(View.VISIBLE);


        Animation a = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                v.getLayoutParams().height = interpolatedTime == 1
                        ? ViewGroup.LayoutParams.WRAP_CONTENT
                        : (int) (targetHeight * interpolatedTime);
                v.requestLayout();
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };

        a.setInterpolator(EasingsConstants.easeInOutQuart);
        a.setDuration(computeDurationFromHeight(v));
        v.startAnimation(a);
    } else {
        Log.d("AnimationUtil", "expand Already expanded ");
    }
}

/**
 * 1dp/ms * multiplier
 */
private static int computeDurationFromHeight(View v) {
    return (int) (v.getMeasuredHeight() / v.getContext().getResources().getDisplayMetrics().density) * DURATION_MULTIPLIER;
}
于 2015-08-10T22:19:57.747 回答