Brad
Brad

Reputation: 11505

TranslateAnimation jumps back to beginning point when done

My TranslateAnimation works, but at the end of the animiation, it jumps back to the original location.

        LinearLayout rl = (LinearLayout) findViewById(R.id.navPanel);

          animation = new TranslateAnimation(
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
              Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 3.0f
          );
          animation.setDuration(500);

          rl.startAnimation(animation);

How can I make it stay at the end location?

Upvotes: 2

Views: 7096

Answers (4)

Oliver Hausler
Oliver Hausler

Reputation: 4977

To avoid repetitive code, you can subclass the AnimatorListenerAdapter and create your own AnimatorListener class where you re-attach the view after the animation, then use it wherever needed instead of the default AnimatorListener.

The class:

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

public class PersistViewAnimatorListener extends AnimatorListenerAdapter {

    private View view; // keep a reference to the view
    public PersistViewAnimatorListener(View view) {
        this.view = view;
    }

    @Override public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);

        // re-attach the view to its parent at its new location
        if (view == null) { return; } // defensive, the view may have been removed while it was animated, do nothing in this case

        ViewGroup parent = (ViewGroup) view.getParent(); // get the parent
        if (parent == null) { return; } // defensive
        int index = parent.indexOfChild(view); // get the index of the view
        parent.removeView(view); // remove the view

        if (parent.getClass().equals(RelativeLayout.class)) { // RELATIVE LAYOUT
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getLayoutParams()); // add the view back at its index with new layout parameters
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0); // left, top, right, bottom; round the float to int
            parent.addView(view, index, layoutParams);
        } else if (parent.getClass().equals(FrameLayout.class)) { // FRAME LAYOUT
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(view.getLayoutParams()); // the same for FrameLayout
            layoutParams.setMargins(Math.round(view.getX()), Math.round(view.getY()), 0, 0);
            parent.addView(view, index, layoutParams);
        } else { // currently no further layouts supported, implement these here
            throw new UnsupportedOperationException("PersistViewAnimatorListener is currently only supported where the parent is either RelativeLayout or FrameLayout.");
        }

        view.setTranslationX(0); view.setTranslationY(0); // reset translated values from the animation

    }
}

And how you use it:

view.animate().yBy(height).setListener(new PersistViewAnimatorListener(view)); // call your custom listener in .setListener() and pass in the view

This solution assumes you are using RelativeLayout or FrameLayout for the parent. Also, it just cares about the position, not size or other properties that can be animated as well.

Upvotes: 1

semih
semih

Reputation: 841

this same problem https://stackoverflow.com/a/6519233/1253065

use animation.setFillAfter(true) , animation.setFillEnabled(true)

Upvotes: 3

Yashwanth Kumar
Yashwanth Kumar

Reputation: 29121

use animation.setFillAfter(true) for your animation to stop it at the end of translation.

http://developer.android.com/reference/android/view/animation/Animation.html#setFillAfter(boolean)

Upvotes: 8

mportuesisf
mportuesisf

Reputation: 5617

The old (pre-3.0) Animation API behaves a bit weird - when it's animating, it merely translates where the view is drawn, but doesn't actually move the view with respect to its parents.

In order to get the view to stay put when the animation is done, you can set an Animation.AnimationListener on your TranslateAnimation. In the onAnimationEnd() method of the listener, you move the view to its final resting place by manipulating the LayoutParams on the view.

Upvotes: 8

Related Questions