Android 動畫播放時退出或隱藏界面時報錯

在動畫正在播放的時候(如果你的動畫跟界面的座標點有關),界面失去隱藏,或者失去了焦點,如果沒有處理,就會報這個空指針異常。

復現場景:

自定義了一個父控件,然後裏面有一些子控件在執行動畫,動畫是根據屏幕的寬高移動,這時候,拉下Android的狀態欄,或者按home鍵,甚至退出程序,都會報一個空指針異常,異常如下圖。

 java.lang.NullPointerException
at android.animation.KeyframeSet.getValue(KeyframeSet.java:183)
at android.animation.PropertyValuesHolder.calculateValue(PropertyValuesHolder.java:660)
at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1174)
at android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1115)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1144)
at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:623)
at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:646)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:531)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

解決:

從異常上
來看這個跟PropertyValuesHolder有關,但最終原因不確定。我是這麼想的,View Animation 底層的動畫執行過程依然跟Animator有關,所以在失去焦點後他便找不到座標點了,所以他的過渡點便成了null。只是這麼想,不知道對不對……

所以我在自定義控件的onVisibilityChanged()中,判斷了是否是顯示狀態,如果是顯示狀態,就讓他繼續播放動畫,否則我就執行動畫的cancel(),方法使之先取消。

cancel方法:取消動畫
【功能說明】該方法用於取消一個動畫的執行。該方法是取得一個正在執行中的動畫的主要方法。cancel方法和startNow方法結合可以實現對動畫執行過程的控制。需要注意的是,通過cancel方法取消的動畫,必須使用reset方法或者setAnimation方法重新設置,纔可以再次執行動畫。

 @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility != VISIBLE){
                View childAt = getChildAt(XXX);
                Animation animation = childAt.getAnimation();
                animation.cancel();
        }else{
            View childAt = getChildAt(XXX);
            childAt.getAnimation().reset();
            childAt.getAnimation().start();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章