2011-01-20 129 views
64

虽然animation.hasEnded设置为true,但似乎在启动onAnimationEnd事件时,Android动画并未真正完成。android动画未完成onAnimationEnd

我希望我的视图可以在它的末尾修改它的背景,但是您可以清楚地看到它在完成前会有一些毫秒的变化。问题是,它会闪烁,因为新的背景出现(=被)缩短了一段时间,直到动画真的结束。

有没有办法让动画的真实结束,或只是防止在短时间内缩小新的背景?

谢谢!


//编辑:我使用的是AnimationListener得到以下电话:

@Override 
public void onAnimationEnd(Animation animation) 
{ 
    View view = (MyView) ((ExtendedScaleAnimation) animation).getView(); 

    view.clearAnimation(); 
    view.requestLayout(); 
    view.refreshBackground(); // <-- this is where the background gets changed 
} 
+1

您是否使用了AnimationListener得到OnAnimationEnd呼叫,或者一些其他的方式?你能从你的项目中发布相关代码,这样我们就可以更好地了解正在发生的事情吗? – FoamyGuy 2011-01-20 18:57:05

+0

当然,谢谢! 我在编辑问题以添加代码和一些细节。 – ShadowMare 2011-01-20 20:05:02

+0

你能否帮我ShadowMare,我有同样的问题,不知道如何解决这个 – 2012-03-14 11:40:51

回答

86

下面是有关这一问题的实际错误的方式http://code.google.com/p/android-misc-widgets/issues/detail?id=8

这基本上指出,当一个AnimationListener附加到动画的onAnimationEnd方法并没有真正很好地工作

解决方法是,以监听在视图中动画事件到你施加动画 例如,如果最初你附着动画侦听到动画像这样

mAnimation.setAnimationListener(new AnimationListener() { 
    @Override 
    public void onAnimationEnd(Animation arg0) { 
     //Functionality here 
    } 
}); 

,然后应用到动画到的ImageView这样

mImageView.startAnimation(mAnimation); 

要解决这个问题,你现在必须创建一个自定义的ImageView

public class MyImageView extends ImageView { 

,然后覆盖View类的onAnimationEnd方法并提供所有功能

@Override 
protected void onAnimationEnd() { 
    super.onAnimationEnd(); 
    //Functionality here 
} 

这是针对此问题的适当解决方法,请提供在over-riden View - > onAnimationEnd方法中的功能,而不是AnimationListener的onAnimationEnd方法附加到Animation上。

这个工作正常,并且不再有任何闪烁的动画结束。希望这可以帮助。

2

出于某种原因,onAnimationStart正常工作,以及onAnimationEnd犯规。因此,继承人如何我原来做的,什么我改变:

尝试1(闪烁): 一)从0像素移动图像80px 二)在onAnimationEnd,设置图像的位置80px

尝试2(无闪烁): a)在onAnimationStart中,将图像的位置设置为80px b)将图像从-80px移动到0px

希望有道理。基本上我翻我做到了

+0

谢谢,这与翻译动画效果很好! – ShadowMare 2011-02-28 15:23:58

32

我当时就被动画里面onAnimationEnd的观点,即带走闪烁 安倍通过调用clearAnimation(来解决这个)它的怪异,为什么会有人不得不这样做,因为onAnimationEnd回调应该被称为只有动画已经结束。但我想,答案就在于框架的深度,以了解view/layout如何处理动画回调。 现在把它当成一个免费的解决方案,这只是起作用。

 animation.setAnimationListener(new AnimationListener() { 

     public void onAnimationEnd(Animation anim) { 
      innerView.clearAnimation(); // to get rid of flicker at end of animation 

      RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams 
      (innerBlockContainer.getWidth(), innerBlockContainer.getHeight()); 

      /* Update lp margin, left/top to update layout after end of Translation */ 
      ViewGroup parent_ofInnerView = (ViewGroup)innerView.getParent(); 
      vp.updateViewLayout(innerBlockContainer, lp); 

     } 

     public void onAnimationRepeat(Animation arg0) {} 

     public void onAnimationStart(Animation arg0) { 
     } 

    }); 

    innerView.startAnimation(animation); 
6

我有一个类似的问题,我用自定义视图类Soham的解决方案。

它工作得很好,但最后,我发现了一个更简单的解决方案,为我工作。

调用view.StartAnimation(animation)后,和我在程序的下一步骤之前,我添加了一个短暂的延迟,这将是足够长的时间让动画完成,但足够短,必须由用户无法察觉:

new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      nextStepInMyProgram(); 
     } 
    }, 200);// delay in milliseconds (200) 
-1

这为我工作:

@Override 
public void onAnimationUpdate(ValueAnimator animation) { 
    if (Float.compare(animation.getAnimatedFraction(),1.0f)) { 
    // animation ended; 
     //do stuff post animation 
    } 
} 
5

我有同样的问题,使用

view.clearAnimation(); 
解决它

view.startAnimation(anim); 
0

一个简单的办法是添加一行到AnimationListener.onAnimationEnd()

@Override 
public void onAnimationEnd(Animation a) { 
    a.setAnimationListener(null); 
    … 
} 
0

annimation也可以停在屏幕旋转。在这种情况下onAnimationEnd()没有被调用。我的解决方法:

animation.setDuration(animationDuration); 
animation.setAnimationListener(new AnimationListenerAdapter() {...}); 
view.startAnimation(animation); 
handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       if(!animation.hasEnded()) { 
        // here you can handle this case 
       } 
      } 
     }, animationDuration + 100); 
0

我有这个问题,因为我Animation不是在主线程启动。 这导致duration为0. 但是,Animation确实播放正确 - 它在执行后立即调用onAnimationEnd()

1

尝试从对象使用getAnimation():

public void onShowListBtnClick(View view) 
    { 
     rightPanel.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_left)); 

     rightPanel.getAnimation().setAnimationListener(new Animation.AnimationListener() {  
      @Override 
      public void onAnimationStart(Animation animation) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onAnimationRepeat(Animation animation) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onAnimationEnd(Animation animation) { 
       // write your code here 
      } 
     }); 
}