I am trying to use AccelerateDecelerateInterpolator and custom it. I can see that Interpolators like DecelerateInterpolator have a "factor" field so you can change its behaviors. but AccelerateDecelerateInterpolator has non. When I am using AccelerateDecelerateInterpolator I almost can't even notice that the interpolator is doing any thing. The animation looks very linear. So, is there any way to factor the AccelerateDecelerateInterpolator or change it in any way? Thanks
You can implement standard easing function with your own Interpolator
.
For example, this would be the implementation for the easeInOutQuint
:
public class MVAccelerateDecelerateInterpolator implements Interpolator {
// easeInOutQuint
public float getInterpolation(float t) {
float x = t*2.0f;
if (t<0.5f) return 0.5f*x*x*x*x*x;
x = (t-0.5f)*2-1;
return 0.5f*x*x*x*x*x+1;
}
}
I tried to define my own TimeInterpolator as a custom AccelerateDecelerateInterpolator. I'm not too happy with the result, but it might give a few ideas. There is also sort of the factor in the code: 0.05f. Check it out:
TimeInterpolator interpolator = new TimeInterpolator() {
@Override
public float getInterpolation(float input) {
return input + 0.05f * (float) Math.sin(2 * Math.PI * input);
}
};
Here is more refined solution. Tangent is probably a better function for the job, than sine. This solution acelerates at begining and in the end. There is also a factor to determine aceleration.
TimeInterpolator interpolator = new TimeInterpolator() {
private final float mFactor = 1.1f; // less than pi/2
private float oldRetVal;
private float oldInputVal;
private double initValue = Math.tan(-mFactor);
private double endValue = 2 * Math.tan(mFactor);
@Override
public float getInterpolation(float input) {
if (oldInputVal != input) {
oldInputVal = input;
oldRetVal = (float) ((Math.tan(mFactor * (2 * input - 1)) - initValue) / endValue);
}
return oldRetVal;
}
};
Android has added PathInterpolatorCompat to the v4 support library. Now using this: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce you can specify a easeInOutQuint, easeInOutQuart, or an easeInOutExpo with ease!
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;
}
And don't forget your build.gradle:
compile "com.android.support:support-v4:22.2.0"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With