Пользовательский андроид AccelerateDecelerateInterpolator

Я пытаюсь использовать AccelerateDecelerateInterpolator и настраиваю его. Я вижу, что у Interpolators, таких как DecelerateInterpolator, есть поле "factor", поэтому вы можете изменить его поведение. но AccelerateDecelerateInterpolator имеет нет. Когда я использую AccelerateDecelerateInterpolator, я почти не могу даже заметить, что интерполятор делает что-то. Анимация выглядит очень линейно. Итак, есть ли способ повлиять на AccelerateDecelerateInterpolator или каким-либо образом изменить его? Благодаря

Ответ 1

Вы можете реализовать стандартную функцию ослабления со своим 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;
    }
}

enter image description here

Ответ 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;
        }
    };

Ответ 3

Android добавила PathInterpolatorCompat в библиотеку поддержки v4. Теперь, используя это: https://gist.github.com/ebabel/8ff41cad01e9ce1dd9ce, вы легко можете указать легкостьInOutQuint, easeInOutQuart или easyInOutExpo!

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"