问题
I want to apply a translate animation
on an Android view
(button) using a custom interpolator
where the easing function is:
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;
}
}
I have an example that uses the custom interpolator like this:
The interpolator is:
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);
}
}
and is used like this:
ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
anim.setInterpolator(new HesitateInterpolator());
My question is:
What are these values b
, c
, d
for?
回答1:
FYI: for people who just want an ease interpolator you can just use myAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
回答2:
I made a library which can solve this problem. AndroidEasingFunctions
回答3:
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:
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.
回答4:
1,2,3 go
- Create a custom cubic bezier curve using this awesome site. And get the control points for the curve. Between 0,0 and 1,1
Interpolator customInterpolator = PathInterpolatorCompat.create(cpX1,cpX2,cpY1,cpY2)
- Add this customInterpolator to any of your animation.
Added a gist. Some more here.
回答5:
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;
}
来源:https://stackoverflow.com/questions/22896605/how-to-apply-easing-animation-function-on-view-in-android