AccelerateDecelerateInterpolator を使用してカスタムしようとしています。DecelerateInterpolator のような Interpolators には「factor」フィールドがあり、その動作を変更できることがわかります。しかし、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 に答える