【问题标题】:How to apply easing animation function on view in Android如何在Android的视图上应用缓动动画功能
【发布时间】:2018-06-24 14:44:04
【问题描述】:

我想使用自定义interpolator 在Android view(按钮)上应用翻译animation,其中缓动函数为:

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());

我的问题是: bcd 这些值是什么?

【问题讨论】:

标签: android animation easing easing-functions


【解决方案1】:

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

【讨论】:

  • 或者:myAnimation.setInterpolator(mContext, android.R.interpolator.accelerate_decelerate);
【解决方案2】:

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

【讨论】:

  • 很棒的图书馆!我觉得有必要注意,不要导入Android的ObjectAnimator和AnimatorSet,而是com.nineoldandroids的,所以编译'com.nineoldandroids:library:2.4.0'也是有必要的
  • 感谢图书馆! :) 只需添加一些有关用法或注意事项的文档。
【解决方案3】:

根据Robert Penner's Easing Functions,如here所述:

t:当前时间,b:begInnIng值,c:变化In值,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 实现中看到的那样。

【讨论】:

  • 感谢您的出色回答,但是您是如何获得您在回答中提到的这些函数的?.. 如何将 Robert 编写的函数转换为仅因子 t 的 java 函数?
  • 非常感谢你的澄清,你能给我提供参考来学习如何从0-1函数规范化函数吗?
  • 对不起,这是数学知识的问题...我已经做到了。您可以使用可视化绘图工具来简化工作,例如rechneronline.de/function-graphs
  • 对不起,我问了很多问题:(,如果我有这样的方程:easeInOutQuad: function (x, t, b, c, d) { if ((t/=d/2)
  • easeInOutQuad 的函数是: (x*2)^2/2 for t0.5
【解决方案4】:

1,2,3 去

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

添加了gist。 一些more here

【讨论】:

    【解决方案5】:

    这是另一个解决方案,最近添加到了 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;
    }
    

    【讨论】:

    • gist 链接不起作用.. EasingsConstants 是自定义类吗?
    • @RikvanVelzen 对此感到抱歉,该链接已从另一个答案中删除,因此我删除了要点。它是一个自定义类,其中包含一组定义来自 easings.net 的值的常量,如下所示: public static final InterpolatoreaseInOutQuad = PathInterpolatorCompat.create(0.455f, 0.03f, 0.515f, 0.955f);
    猜你喜欢
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多