How to apply easing animation function on view in Android

后端 未结 5 2041
情深已故
情深已故 2020-12-14 04:11

I want to apply a translate animation on an Android view (button) using a custom interpolator where the easing function is:

         


        
相关标签:
5条回答
  • 2020-12-14 04:39

    1,2,3 go

    1. Create a custom cubic bezier curve using this awesome site. And get the control points for the curve. Between 0,0 and 1,1
    2. Interpolator customInterpolator = PathInterpolatorCompat.create(cpX1,cpX2,cpY1,cpY2)
    3. Add this customInterpolator to any of your animation.

    Added a gist. Some more here.

    0 讨论(0)
  • 2020-12-14 04:52

    According to Robert Penner's Easing Functions, as stated here:

    t: current time, b: begInnIng value, c: change In value, d: duration

    If you want to implement your custom Interpolator, you have to make something like this:

    (this would be the implementation for the 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;
        }
    }
    

    Edit: to implement the easing function you need some math knowledge, considering that the getInterpolation method gets only the t parameter, from 0.0 to 1.0.

    So basically you need to develop a y(t) function, with t from 0 to 1, and with y values from 0 to 1, as shown below:

    enter image description here

    What you change is the curve to get from 0 to 1 (in the image the green line is the linear one, for example). You need to 'normalize' the easing functions to remain in the (0, 1) x (0, 1) square, as you can see in my easeInOutQuint implementation.

    0 讨论(0)
  • 2020-12-14 04:53

    FYI: for people who just want an ease interpolator you can just use myAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

    0 讨论(0)
  • 2020-12-14 04:53

    I made a library which can solve this problem. AndroidEasingFunctions

    0 讨论(0)
  • 2020-12-14 04:53

    Here is another solution, made possible by a recent addition to android's support library: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce

    and an example in use:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题