我正在尝试使用 AccelerateDecelerateInterpolator 并对其进行自定义。我可以看到像 DecelerateInterpolator 这样的插值器有一个“因子”字段,所以你可以改变它的行为。但 AccelerateDecelerateInterpolator 没有。当我使用 AccelerateDecelerateInterpolator 时,我几乎没有注意到插值器正在做任何事情。动画看起来非常线性。那么,有没有办法考虑 AccelerateDecelerateInterpolator 或以任何方式改变它?谢谢
问问题
7853 次
3 回答
14
您可以使用自己的Interpolator
. 例如,这将是以下的实现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;
}
}
于 2014-04-11T14:38:33.940 回答
2
我试图将自己的 TimeInterpolator 定义为自定义的 AccelerateDecelerateInterpolator。我对结果不太满意,但它可能会提供一些想法。代码中还有一个因素:0.05f。看看这个:
TimeInterpolator interpolator = new TimeInterpolator() {
@Override
public float getInterpolation(float input) {
return input + 0.05f * (float) Math.sin(2 * Math.PI * input);
}
};
这是更精致的解决方案。切线可能比正弦函数更适合这项工作。该解决方案在开始和结束时都会加速。还有一个决定加速度的因素。
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;
}
};
于 2013-09-17T16:42:10.477 回答
1
Android 已将 PathInterpolatorCompat 添加到 v4 支持库中。现在使用这个:https : //gist.github.com/ebabel/8ff41cad01e9ce1dd9ce 您可以轻松指定easeInOutQuint、easeInOutQuart 或easeInOutExpo!
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;
}
不要忘记你的 build.gradle:
compile "com.android.support:support-v4:22.2.0"
于 2015-08-07T00:44:10.103 回答