2010-10-07 146 views
48

我正在使用xml定义的动画将视图从屏幕上滑下。问题是,只要动画完成,重置到原来的位置。我需要知道如何解决这个问题。这里的XML:Android:完成后动画位置重置

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> 
    <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/></set> 

下面是我用它来称呼它为Java的:

homeScrn = (View)findViewById(R.id.homescreen); 
    slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); 

    //Set Click Listeners For Menu 
    btnHelp.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true); 
      homeScrn.startAnimation(slideLeftOut); 
     } 
    }); 

所以基本上会发生什么是我一个充气下方的视图。然后,我将视图置于左侧顶部。一旦它离开屏幕并且动画结束,它就会重置它的位置。

回答

69

动画按预期工作。仅仅因为你给动画做了什么并不意味着你实际上移动了它。动画只影响动画本身的绘制像素,而不影响小部件的配置。

您需要添加一个AnimationListener,并在onAnimationEnd()方法,做一些让你的移动永久性的(例如,消除了对从其父顶视图,标志着在顶部视图具有可识别性GONE)。

+0

啊哈哈!正是我需要的。谢谢! – LoneWolfPR 2010-10-07 20:01:14

+4

但是我应该怎么做,如果相同有slideIn。因为它实际上没有移动,那么我如何slideIn我有slideOut? – Ads 2011-12-13 13:45:08

+0

即使你做了* permeneny *在'onAnimationEnd()'中移动你的'View',它会**闪烁**。检查:http://stackoverflow.com/questions/2650351/android-translateanimation-resets-after-animation – 2014-02-27 12:52:21

14

我可能是有点晚在回答,但我对这个解决方案:

只需添加android:fillAfter=true 在XML

+14

它不适用于翻译动画。它仅适用于缩放动画。 – Ads 2011-12-13 13:38:44

+3

它也不适用于旋转。 – 2013-06-04 11:38:31

+1

它适用于旋转。 – 2016-08-01 02:29:57

1

我去了同样的问题,并在设置marginLeft解决它OnAnimationEnd()..

MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams(); params.setMargins(this.getWidth()*position, 0,0,0); this.setLayoutParams(params);

9

您可以使用

fillAfter=true 
fillEnabled=true 

您的视图将不会重置为原始位置,但如果您在视图中有某些按钮或其他位置,则它们的位置不会改变。

您必须使用ObjectAnimator,它从API 11级别开始工作。它改变自动查看位置,

这里是例子

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX); 
objectAnimator.setDuration(1000); 
objectAnimator.start(); 

感谢JUL他answer

如果没有找到object animator您的应用程序,改变从Project -> properties -> Android API级别,比import android.animation.ObjectAnimator;

问候海克

88

终于有了一种方法来解决,要做到这一点正确的做法是setFillAfter(true),如果要定义XML格式的动画,那么你应该做一些这样的事

<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/decelerate_interpolator" 
    android:fillAfter="true"> 

    <translate 
     android:fromXDelta="0%" 
     android:toXDelta="-100%" 
     android:duration="1000"/> 

</set> 

你可以看到,我已在定义filterAfter="true"

set标记,如果您尝试在translate标记中定义它,它将不起作用,可能是框架中的错误

,然后在代码

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out); 
someView.startAnimation(anim); 

OR

TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0); 

animation.setFillAfter(true); 

animation.setDuration(1800); 

someView.startAnimation(animation); 

那么它一定会努力!

现在这有点棘手,它看起来像是视图实际上移动到新的位置,但实际上视图的像素被移动,即您的视图实际上处于其初始位置但不可见,您可以测试它是否有你在你看来一些按钮或点击视图(在我的布局的情况下),要解决,你有你的看法/布局手动移动到新的位置

public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) 

new TranslateAnimation(-90, 150, 0, 0); 

现在我们可以看到,我们的动画将从-90 x轴开始到150 x轴

所以我们要做的就是设置

someView.setAnimationListener(this); 

public void onAnimationEnd(Animation animation) 
{ 
    someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight()); 
} 
现在

让我解释一下public void layout (int left, int top, int right, int botton)

它移到您的布局到新位置的第一个参数定义的左边,我们是,因为翻译的动画有动画我们的观点到150 x轴,顶部是0,因为我们没有动画Y轴,现在在右边我们已经完成了someView.getWidth() + 150基本上我们得到了我们的视图的宽度和添加,因为我们现在左移动到150 x轴以使视图宽度达到原始宽度,底部等于我们视图的高度。

我希望你现在人们明白翻译的概念,还是你有,你可以问注释部分就任何问题,我感到很高兴帮助:)

编辑不要使用layout()方法因为它可以被框架调用,当查看无效并且您的更改无效时,请使用LayoutParams根据您的要求设置您的布局参数

+2

针对此方案的更好的答案。 – Vivekanand 2013-04-04 11:04:59

+0

感谢您的解释我也使用这种方法,只有这种方法的问题是当动画结束动画视图闪烁。 – user65721 2013-05-28 19:39:14

+1

@ user65721你是否将你的观点转移到新的位置?并且你尝试过'setFillEnabled()'? – 2013-05-29 05:38:17

1

此问题已困扰超过一周。 穆罕默德的回答指出了我解决这个问题的方法。

我用sever布局来实现动画的侧面菜单。 “ ”view.layout不会持久化,你应该使用LayoutParams,它将是持久的。“

这里是我的解决方案: (使用什么样的LayoutParameter的是依赖于自己父母的布局):

@Override 
public void onAnimationEnd(Animation animation) { 
FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight); 
layoutParams.setMargins((int) -(screenWidth * RATE), 0, 
      (int) (screenWidth - screenWidth * RATE), screenHeight); 
    for(View v:views) { 

     v.setLayoutParams(layoutParams); 
     //v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); 
     v.clearAnimation(); 
    } 
} 
5

您需要添加此命令:

final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0); 
animSlideLeft.setFillAfter(true);