如何为View的翻译设置动画

时间:2012-06-25 11:18:09

标签: android android-animation android-view

在第一次点击按钮时,我想沿x轴滑动View(向右滑动200像素)。在第二次按下按钮时,我想将View沿x轴向后滑动到原始位置。

View.setTranslationX(float)方法分别通过调用myView.setTranslationX(200);myView.setTranslationX(0);将视图跳转到目标水平位置。任何人都知道如何将<{1}} 移动到目标水平位置?

  

注1: View不好,因为它实际上并没有移动   TranslateAnimation只是呈现出它移动的幻觉。

     

注2:我在提出问题时没有意识到自{API} 11级引入了ViewsetTranslationX(float)方法。如果你'重新定位Honeycomb(API Level 11),然后Gautam K的答案就足够了。否则,请参阅我的答案以获得建议的解决方案。

3 个答案:

答案 0 :(得分:26)

尝试研究ObjectAnimator及其超类价值动画师

你可以做这样的事 ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200); 然后 anim.start();

使用boolean值并在对象动画制作工具中将其与200,0切换回来

PS:您可以使用setDuration方法设置动画完成所需的时间

编辑:

尝试查看提供向后兼容性的support library

修改

正如@AdilHussain指出的那样,有一个名为nineoldandroids的库可用于旧机器人的相同目的。

答案 1 :(得分:5)

这个让我难以忍受了几天(让它在冰淇淋三明治之前上班),但我想我终于到了那儿! (感谢Gautam K和Mike Israel的领导)我最后做的是扩展我的View(一个FrameLayout)以根据需要开始翻译右/左动画并听取动画结束,以便适当地重新定位我的FrameLayout右/左,如下所示:

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);
    }
  }
}

最后,要向右/向左滑动SlidingFrameLayout,您所要做的就是调用SlidingFrameLayout.toggleSlide()方法。当然,您可以调整此SlidingFrameLayout以便用于滑动更多像素,滑动更长时间等,但这应该足以让您入门:)

答案 2 :(得分:2)

我有类似的问题,如果你现在调用setFillAfter(android bug),TranslateAnimation实际上会移动视图。我必须做类似的事情,所以我说,嘿,让我们使用动画监听器,然后将所有内容移动到正确的位置。不幸的是,动画监听器也存在一个错误(stackoverflow solution)。所以我根据stackoverflow solution中的解决方案创建了自己的布局类,我很乐意去:)