Reputation: 11505
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
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
Reputation: 841
this same problem https://stackoverflow.com/a/6519233/1253065
use animation.setFillAfter(true) , animation.setFillEnabled(true)
Upvotes: 3
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
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