Android Multiple AnimatorSet reset

android, animation

Solution

Reversing the effects of an `AnimatorSet` can be tricky simply because there is no "reverse" method. The easiest method in this case, would probably simply be another `AnimatorSet` that does the opposite of the original. The issue here would be is your `AnimatorListener` could be out of sync. If you do this way and you want to keep the boolean, then you'd have to implement it as somewhat of a semaphore.

public static class AnimatorTracker implements AnimatorListener{
    int counter;

    public AnimatorTracker() {
      counter = 0;
    }

    public boolean isAnimating() {
      return counter == 0;
    }

    @Override
    public void onAnimationStart(Animator animation) {
      counter++;
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
      counter--;
    }

    @Override
    public void onAnimationCancel(Animator animation) {
      // Canceling an animation invokes onAnimationEnd, so nothing needs to be done.
    }
  }

Then just make the sets the same way you just did:

AnimatorTracker tracker = new AnimatorTracker(); // or make it a global reference
AnimatorSet set = new AnimatorSet();
AnimatorSet reverseSet = new AnimatorSet();

ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor);
ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor);
ValueAnimator reverseV1 = ObjectAnimator.ofFloat(v, "scaleX", 1.0f);
ValueAnimator reverseV2 = ObjectAnimator.ofFloat(v, "scaleY", 1.0f);


set.addListener(tracker);
set.setDuration(100);
set.playTogether(v1, v2);

reverseSet.addListener(tracker);
reverseSet.setDuration(100);
reverseSet.playTogether(reverseV1, reverseV2);

Call `set.start()` when you want to animate forward. Call `reverseSet.start()` when you want to animate back.

Problem

Hi I am applying multiple animations to a view using AnimatorSet and ValueAnimator. When the user touches the view, successive animations are applied to the view. I do this to have a "zooming effect" when the user is moving his fingers on the view. The view is a custom gallery. Here is the code for animation: ``` private void createAnim(final View v) { animating = true; if (D) Log.i(TAG, "sarting animation"); try { v.clearAnimation(); v.getAnimation().reset(); } catch (Exception e) { } set = new AnimatorSet(); set.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { if (D) Log.i(TAG, "Animation ended"); animating = false; } @Override public void onAnimationCancel(Animator animation) { animating = false; if (D) Log.i(TAG, "Animation cancelled"); } }); set.setDuration(100); ValueAnimator v1 = ObjectAnimator.ofFloat(v, "scaleX", mScaleFactor); ValueAnimator v2 = ObjectAnimator.ofFloat(v, "scaleY", mScaleFactor); animationList.add(v1); animationList.add(v2); set.playTogether(v1, v2); set.start() } ``` I have an onTouchListener and on action move I successively call this method increasing or decreasing the mScaleFactor. When the user releases the finger I would like the view to go back to previous state, I mean to erase all animations applied as if they were never applied to view. The problem is you can easily do that for one animation but for many like that I just can't find the right way. Here is what I have tried: -Adding the animations to an ArrayList and doing animation.reverse() on each one of them with a delay of +100 added to each of them so the execute one after another but the end result just doesn't seem exactly the same as before animations. v.clearAnimation(); only cancels the last animation v.getAnimation().reset(); same only works for last/active animation. Is there a method to just get the view back as it was before any animation has been started? Thanks a lot

Original source