2011-01-20 167 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 
      } 
     }); 
}