Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate a View's translation

Tags:

At the first click of a button, I want to slide a View along the x-axis (by 200 pixels to the right let's say). And on the second press of the button, I want to slide the View back along the x-axis to its original position.

The View.setTranslationX(float) method jumps the View to the target horizontal locations with calls myView.setTranslationX(200); and myView.setTranslationX(0); respectively. Anyone know how I can slide the View to the target horizontal locations instead?

Note 1: A TranslateAnimation is no good since it doesn't actually move the View but only presents the illusion of it moving.

Note 2: I didn't realise at the time of posing the question that the setTranslationX(float) and setTranslationY(float) methods were introduced as of API Level 11. If you're targeting Honeycomb (API Level 11) upwards, then Gautam K's answer will suffice. Otherwise, see my answer for a suggested solution.

like image 833
Adil Hussain Avatar asked Jun 25 '12 11:06

Adil Hussain


2 Answers

Try looking into ObjectAnimator and its super class Value Animator

you can do something like this ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200); and then anim.start();

Use a boolean value and toggle it with 200,0 in the object animator to slide back

PS: you can use setDuration method to set how long the animation should take to complete

Edit :

Try looking at the support library which provides backward compatibility.

Edit

As @AdilHussain pointed out there is a library called nineoldandroids which can be used for the same purpose on older androids.

like image 120
Gautam Avatar answered Oct 13 '22 16:10

Gautam


This one's had me stumped for a fair few days (getting it to work pre- Ice Cream Sandwich) but I think I've finally got there! (thanks to Gautam K and Mike Israel for the leads) What I did in the end was to extend my View (a FrameLayout) to start the translate right/left animations as required and to listen for the end of the animations in order to relocate my FrameLayout right/left as appropriate, as follows:

public class SlidingFrameLayout extends FrameLayout {   private final int durationMilliseconds = 1000;   private final int displacementPixels = 200;    private boolean isInOriginalPosition = true;   private boolean isSliding = false;    public SlidingFrameLayout(Context context)   {     super(context);   }    public SlidingFrameLayout(Context context, AttributeSet attrs)   {     super(context, attrs);   }    public SlidingFrameLayout(Context context, AttributeSet attrs, int defStyle)   {     super(context, attrs, defStyle);   }    @Override   protected void onAnimationEnd()   {     super.onAnimationEnd();      if (isInOriginalPosition)       offsetLeftAndRight(displacementPixels);     else       offsetLeftAndRight(-displacementPixels);      isSliding = false;     isInOriginalPosition = !isInOriginalPosition;   }    @Override   protected void onLayout(boolean changed, int left, int top, int right, int bottom)   {     super.onLayout(changed, left, top, right, bottom);      // need this since otherwise this View jumps back to its original position     // ignoring its displacement     // when (re-)doing layout, e.g. when a fragment transaction is committed     if (changed && !isInOriginalPosition)       offsetLeftAndRight(displacementPixels);   }    public void toggleSlide()   {     // check whether frame layout is already sliding     if (isSliding)       return; // ignore request to slide      if (isInOriginalPosition)       startAnimation(new SlideRightAnimation());     else       startAnimation(new SlideLeftAnimation());      isSliding = true;   }    private class SlideRightAnimation extends TranslateAnimation   {     public SlideRightAnimation()     {       super(           Animation.ABSOLUTE, 0,           Animation.ABSOLUTE, displacementPixels,           Animation.ABSOLUTE, 0,           Animation.ABSOLUTE, 0);        setDuration(durationMilliseconds);       setFillAfter(false);     }   }    private class SlideLeftAnimation extends TranslateAnimation   {     public SlideLeftAnimation()     {       super(           Animation.ABSOLUTE, 0,           Animation.ABSOLUTE, -displacementPixels,           Animation.ABSOLUTE, 0,           Animation.ABSOLUTE, 0);        setDuration(durationMilliseconds);       setFillAfter(false);     }   } } 

And, lastly, to slide the SlidingFrameLayout right/left, all you've got to do is call the SlidingFrameLayout.toggleSlide() method. Of course you can tweak this SlidingFrameLayout for your purposes to slide a greater number of pixels, to slide for longer etc, but this should be sufficient to get you started :)

like image 44
Adil Hussain Avatar answered Oct 13 '22 17:10

Adil Hussain