How do I wait for AnimationDrawable to end before

2019-03-03 19:23发布

问题:

so I have an AnimationDrawable to move a character one space on the screen. The animation works fine, but I need to stall out the rest of the GUI from refreshing the screen. Basically when the map moves, the game has to refresh the screen to update the new location. The code for the redraw is inside of the game class, and the animation is in the image adapter for the gridview that displays the actual game board. Here's the two lines of code that are trouble.

    playerAdapter.animateLeft();
    redraw();

The first line calls the adapter which has the two animations that need to happen, both take 700ms. Then, redraw updates the board itself. The problem is, redraw doesn't wait for the animations. I've tried using sleep and stuff like that but that just pauses the whole damn thing and nothing happens. I think I need to use Threads or Handlers but I'm unsure how that works. Any ideas? All help is much appreciated :)

回答1:

Try:

YourAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) { }

    @Override
    public void onAnimationEnd(Animation animation) {
        //Ended
    }

    @Override
    public void onAnimationRepeat(Animation animation) { }
});

EDIT: Oops. Didn't read the drawable part. Here's a recursive function I use to check if all frames are over:

 private void checkIfAnimationDone(AnimationDrawable anim){
        final AnimationDrawable a = anim;
        int timeBetweenChecks = 300;
        Handler h = new Handler();
        h.postDelayed(new Runnable(){
            public void run(){
                if (a.getCurrent() != a.getFrame(a.getNumberOfFrames() - 1)){
                    checkIfAnimationDone(a);
                } else{
                    Toast.makeText(getApplicationContext(), "ANIMATION DONE!", Toast.LENGTH_SHORT).show();
                }
            }
        }, timeBetweenChecks);
    };

You could also log the time when you start the animation, and add the duration (which you know before hand) to it to get the ending time. However, this can be inaccurate, as setting and starting the animation takes a bit of time as well.



回答2:

Another interesting solution:

animation.start();
long totalDuration = 0;
for(int i = 0; i< animation.getNumberOfFrames();i++){
     totalDuration += animation.getDuration(i);
}                      
Timer timer = new Timer();
TimerTask timerTask = new TimerTask(){
     @Override
         public void run() {
              animation.stop();
    }
 };
timer.schedule(timerTask, totalDuration);