Reversing an Animation

AndroidAnimation

Android Problem Overview


I have an ImageView that gets animated when it is added to a layout. When it is removed, I want to reverse the same animation.

Is there a way to reverse an animation in android without recoding it and reversing the parameters?

Android Solutions


Solution 1 - Android

No, sadly you cannot do it with the Animation object. But you can simulate it using an interpolator that will inverse the animation:

package com.example.android;

import android.view.animation.Interpolator;

public class ReverseInterpolator implements Interpolator {
	@Override
	public float getInterpolation(float paramFloat) {
		return Math.abs(paramFloat -1f);
	}
}

Then on your animation you can set your new interpolator:

myAnimation.setInterpolator(new ReverseInterpolator());

Solution 2 - Android

If you are using Object or ValueAnimator to animate the view, you can simply do

ValueAnimator myAnimator = new ValueAnimator();  
myAnimator.reverse()

Documentation can be found here.

Solution 3 - Android

Based on pcans idea, you can reverse any interpolator, not just linear.

class ReverseInterpolator implements Interpolator{
    private final Interpolator delegate;

    public ReverseInterpolator(Interpolator delegate){
        this.delegate = delegate;
    }

    public ReverseInterpolator(){
        this(new LinearInterpolator());
    }

    @Override
    public float getInterpolation(float input) {
        return 1 - delegate.getInterpolation(input);
    }
}

Usage

ReverseInterpolator reverseInterpolator = new ReverseInterpolator(new AccelerateInterpolator())
myAnimation.setInterpolator(reverseInterpolator);

Solution 4 - Android

I have a similar approach to pcans buts slightly different. It takes an Interpolator and will effectively pass out values that would be the same as using the passed in Interpolator normally and then in REVERSE mode. Saves you having to think about the buggy implementations of Animation.REVERSE across Android. See the code here

public class ReverseInterpolator implements Interpolator {

    private final Interpolator mInterpolator;

    public ReverseInterpolator(Interpolator interpolator){
        mInterpolator = interpolator;
    }

    @Override
    public float getInterpolation(float input) {
        return mInterpolator.getInterpolation(reverseInput(input));
    }

    /**
     * Map value so 0-0.5 = 0-1 and 0.5-1 = 1-0
     */
    private float reverseInput(float input){        
        if(input <= 0.5)
            return input*2;
        else
            return Math.abs(input-1)*2;        
    }
}

Solution 5 - Android

Simplest solution i came up with

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <alpha
        android:duration="2000"
        android:fromAlpha="0.1"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toAlpha="1.0">
    </alpha>
</set>

Solution 6 - Android

You can make the code remember the original position and the end position. And let your code dynamically get those values when triggering animation.

Solution 7 - Android

If you are using animation from xml then an easy way is to made an exact same reverse animation to original animation. Add Animation.AnimationListener to original animation and in onAnimationEnd method start the reverse animation.

Solution 8 - Android

this worked for me

 ObjectAnimator anim = ObjectAnimator.ofFloat(imageViewUpb, "rotation", rotationAngle, rotationAngle + 180);

            if (linearLayoutb.getVisibility()==GONE){

                linearLayoutb.setVisibility(VISIBLE);
                anim.setDuration(500);
                anim.start();
                rotationAngle += 180;
                rotationAngle = rotationAngle%360;
        imageViewUpb.animate().rotation(rotationAngle).setDuration(500).start();

            }else{
                
                linearLayoutb.setVisibility(GONE);
                anim.setDuration(500);
                anim.start();
                rotationAngle += 180;
                rotationAngle = rotationAngle%180;
imageViewUpDownb.animate().rotation(rotationAngle).setDuration(500).start();
                
            }

linearlayoutb is the view that expands when the imageviewUpb faces up

make int rotationAngle = 0; global parameter

Solution 9 - Android

You need to use RepeatCount and RepeatMode

kotlin

   var anim = TranslateAnimation(0, 100, 0, 100)
   anim.repeatCount = Animation.INFINITE // you cant 1,2,...
   anim.repeatMode = Animation.REVERSE // you can set REVERSE or RESTART
   anim.start()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpbreaultView Question on Stackoverflow
Solution 1 - AndroidpcansView Answer on Stackoverflow
Solution 2 - AndroidthehayroView Answer on Stackoverflow
Solution 3 - AndroidIlya GazmanView Answer on Stackoverflow
Solution 4 - AndroidDoriView Answer on Stackoverflow
Solution 5 - AndroidlarisoftView Answer on Stackoverflow
Solution 6 - AndroiddrawView Answer on Stackoverflow
Solution 7 - AndroidKhurram ShehzadView Answer on Stackoverflow
Solution 8 - AndroidGoodlifeView Answer on Stackoverflow
Solution 9 - AndroidRasoul MiriView Answer on Stackoverflow