Анимация ImageView с помощью V-образной анимации - PullRequest
0 голосов
/ 23 декабря 2019

Я пытаюсь переместить изображение справа налево, выполняя "V" (вверх-вниз). Вот изображение, описывающее то, что я преследую: V shaped animation

Я пытался использовать ObjectAnimator и AnimatorSet, но я не понимаю, что я прыгал, чтобы получить. И трудно понять, почему я получаю что-то еще. Вот мой текущий код:

/**
 * translateLeft = -160dp
 * translateDown = 25dp
 * translateUp   = -25dp
 */
private void vShapedAnimation () {
    AnimatorSet upDownSet = new AnimatorSet();
    AnimatorSet downUpSet = new AnimatorSet();
    AnimatorSet finalSet = new AnimatorSet();
    ObjectAnimator rightToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
    ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
    ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateUp));
    upDownSet.playTogether(
            rightToLeft,
            upDown
    );
    downUpSet.playTogether(
            rightToLeft,
            downUp
    );
    finalSet.playSequentially(
            upDownSet,
            downUpSet
    );
    finalSet.setDuration(300);
    finalSet.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            animation.removeListener(this);
            animation.setDuration(0);
            animation.setInterpolator(new ReverseInterpolator());
            animation.start();
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
    finalSet.start();
}

Отсюда ReverseInterpolator в AnimatorListener:

Как сбросить ObjectAnimator в исходное состояние?

Я планирую немного повернуть изображение одновременно. И если бы буква V могла слегка изогнуться внутрь, это было бы идеально. Но если поначалу кто-нибудь сможет помочь мне сделать базовую анимацию, это будет высоко оценено.

1 Ответ

0 голосов
/ 23 декабря 2019

ObjectAnimator есть свои странные моменты, но я наконец-то понял (по крайней мере, достаточно, чтобы решить мою собственную проблему).

Подвох в том, что в последовательности анимаций лучшевсегда указывать начальную и конечную позиции. В вопросе, который я написал, три ObjectAnimators получили только конечную позицию. Это заставляет анимацию начинаться в странных местах.

Используя пример псевдокода, если вы хотите перейти от А к С, пройдя через В, вам нужно записать это так:

ObjectAnimator AtoB_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, A.x, B.x - A.x);
ObjectAnimator BtoC_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, B.x - A.x, C.x - A.x);
ObjectAnimator AtoB_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, A.y, B.y - A.y);
ObjectAnimator BtoC_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, B.y - A.y, C.y - A.y);

ВАЖНО: всегда используйте dp измерения. Никогда не используйте px измерения. Вот почему в моем коде я использую this.getResources().getDimensionPixelOffset(). Он преобразует значение dp в значение px, соответствующее каждому разрешению экрана.

Теперь для моего рабочего кода:

private void vShapedAnimation() {
    AnimatorSet upDownSet = new AnimatorSet();
    AnimatorSet downUpSet = new AnimatorSet();
    AnimatorSet finalSet = new AnimatorSet();
    ObjectAnimator rightToHalf = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
    ObjectAnimator halfToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft));
    ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
    ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown), 0);
    upDownSet.playTogether(
            rightToHalf,
            upDown
    );
    downUpSet.playTogether(
            halfToLeft,
            downUp
    );
    finalSet.playSequentially(
            upDownSet,
            downUpSet
    );
    finalSet.setInterpolator(new LinearInterpolator());
    finalSet.setDuration(300);
    finalSet.start();
}
...