如何动画视图的转换 [英] How to animate a View's translation

查看:120
本文介绍了如何动画视图的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个按钮的第一次点击,我想滑动查看沿x轴(由200像素的权利,让我们说)。而在按键的第二preSS,我想滑动查看返回沿x轴到原来的位置。

View.setTranslationX(浮点)方法的的查看到目标水平位置的调用 myView.setTranslationX (200); myView.setTranslationX(0); 分别。任何人都知道我可以的幻灯片的的查看目标水平位置呢?

  

注意1: A TranslateAnimation 是没有好处,因为它实际上并没有动   在查看但只有presents它移动的错觉。

     

注意2:我不知道在提出这个问题的时候了 setTranslationX(浮点) setTranslationY(浮点)方法进行。如果你的目标蜂窝(API等级11)以上,那么高塔姆·K公司的答案就足够了介绍,作为API级别11。否则,请参阅我的回答对一个建议的解决方案。

解决方案

这一次的让我难倒了公平几天(得到它的工作pre型冰淇淋三明治),但我想我终于到了那里! (感谢高塔姆·K和迈克以色列引线)我到底做的是延长我的查看(A 的FrameLayout )开始转换左/右动画的要求,并以重新定位监听动画的结束我的的FrameLayout 左/右视情况如下:

 公共类SlidingFrameLayout扩展的FrameLayout
{
  私人最终诠释durationMilliseconds = 1000;
  私人最终诠释displacementPixels = 200;

  私人布尔isInOriginalPosition = TRUE;
  私人布尔isSliding = FALSE;

  公共SlidingFrameLayout(上下文的背景下)
  {
    超(上下文);
  }

  公共SlidingFrameLayout(上下文的背景下,ATTRS的AttributeSet)
  {
    超(背景下,ATTRS);
  }

  公共SlidingFrameLayout(上下文的背景下,ATTRS的AttributeSet,INT defStyle)
  {
    超(背景下,ATTRS,defStyle);
  }

  @覆盖
  保护无效onAnimationEnd()
  {
    super.onAnimationEnd();

    如果(isInOriginalPosition)
      offsetLeftAndRight(displacementPixels);
    其他
      offsetLeftAndRight(-displacementPixels);

    isSliding = FALSE;
    !isInOriginalPosition = isInOriginalPosition;
  }

  @覆盖
  保护无效onLayout(布尔改变,诠释离开,诠释顶部,诠释权,诠释下)
  {
    super.onLayout(改,左,上,右,下);

    //需要这个,否则这个视图跳回原来的位置
    //忽略它的位移
    //在(再)进行布局,例如当一个片段事务提交
    如果(改变&安培;&安培;!isInOriginalPosition)
      offsetLeftAndRight(displacementPixels);
  }

  公共无效toggleSlide()
  {
    //检查框架布局是否已经沉没
    如果(isSliding)
      返回; //忽略请求下滑

    如果(isInOriginalPosition)
      startAnimation(新SlideRightAnimation());
    其他
      startAnimation(新SlideLeftAnimation());

    isSliding = TRUE;
  }

  私有类SlideRightAnimation扩展TranslateAnimation
  {
    公共SlideRightAnimation()
    {
      超(
          Animation.ABSOLUTE,0,
          Animation.ABSOLUTE,displacementPixels,
          Animation.ABSOLUTE,0,
          Animation.ABSOLUTE,0);

      setDuration(durationMilliseconds);
      setFillAfter(假);
    }
  }

  私有类SlideLeftAnimation扩展TranslateAnimation
  {
    公共SlideLeftAnimation()
    {
      超(
          Animation.ABSOLUTE,0,
          Animation.ABSOLUTE,-displacementPixels,
          Animation.ABSOLUTE,0,
          Animation.ABSOLUTE,0);

      setDuration(durationMilliseconds);
      setFillAfter(假);
    }
  }
}
 

和,最后,以滑动 SlidingFrameLayout 左/右,你所要做的就是调用 SlidingFrameLayout.toggleSlide()方法。当然,你可以调整这个 SlidingFrameLayout 你的目的下滑更多的像素,滑动更长等等,但是这应该足以让你开始:)

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.

解决方案

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

这篇关于如何动画视图的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆