How to animate a View's translation

前端 未结 3 1445
深忆病人
深忆病人 2020-12-14 18:22

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 t

相关标签:
3条回答
  • 2020-12-14 18:47

    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 :)

    0 讨论(0)
  • 2020-12-14 19:00

    I had a similar issue, TranslateAnimation does actually move the view if you call setFillAfter now (android bug). I had to do something similar so I said, hey lets use an animation listener and then just move everything to the correct location. Unfortunately there is a bug on animation listeners as well (stackoverflow solution). So I created my own layout class according to the solution in the stackoverflow solution and I was good to go :)

    0 讨论(0)
  • 2020-12-14 19:02

    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.

    0 讨论(0)
提交回复
热议问题