14

AccelerateDecelerateInterpolator を使用してカスタムしようとしています。DecelerateInterpolator のような Interpolators には「factor」フィールドがあり、その動作を変更できることがわかります。しかし、AccelerateDecelerateInterpolator にはありません。AccelerateDecelerateInterpolator を使用しているときは、補間器が何かをしていることにほとんど気付かないほどです。アニメーションは非常に直線的に見えます。では、AccelerateDecelerateInterpolator を因数分解したり、何らかの方法で変更したりする方法はありますか? ありがとう

4

3 に答える 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 に答える