How to animate a View's translation

前端 未结 3 1455
深忆病人
深忆病人 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 :)

提交回复
热议问题