Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

java - Android Animation: Wait until finished?

I would like to wait until an animation is finished* in an Android ImageView before continuing program execution, what is the proper way to do this?

  • (in this context "finished" means that it runs through all of its frames exactly one time and stops on the last one. I am unclear whether this animation will be an android:oneshot="true" animation because I will be using it multiple times, but it will not be run continuously but intermittently)

Research/Guesses:

A. At heart my question seems to be a Java thread question because the Android AnimationDrawable implements Java.lang.Runnable. So maybe threads are the solution. Perhaps the answer will include join?

B. The approach of others seems to have been to use AnimationListener, this seems difficult and needlessly complex for my simple needs. Plus I'm not exactly sure how to do it.

C. The AnimationDrawable class has a (boolean) isRunning method which could probably be used in a while loop (i.e. while(anim.isRunning()){wait(100ms)}). But I have a gut feeling that this is the wrong approach. Although something similar seems to be mentioned in the concurrency tutorial

Code Snippet

   this.q_pic_view.setImageResource(0);
    this.q_pic_view.setBackgroundResource(R.drawable.animation_test);
    AnimationDrawable correct_animation = (AnimationDrawable) this.q_pic_view.getBackground();
    correct_animation.start();

    //here I tried to implement option C but it didn't work
    while(correct_animation.isRunning()){
        try {
           Thread.sleep(20);
        } catch (InterruptedException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
        }
    }

Animation

<?xml version="1.0" encoding="utf-8"?>
<animation-list android:id="@+id/AnimTest" android:oneshot="true" xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/animtest001" android:duration="33"/>
  <item android:drawable="@drawable/animtest002" android:duration="100"/>
  <item android:drawable="@drawable/animtest003" android:duration="66"/>
  <item android:drawable="@drawable/animtest004" android:duration="66"/>
  <item android:drawable="@drawable/animtest005" android:duration="33"/>
  <item android:drawable="@drawable/animtest006" android:duration="66"/>
  <item android:drawable="@drawable/animtest007" android:duration="33"/>
  <item android:drawable="@drawable/animtest008" android:duration="66"/>
  <item android:drawable="@drawable/animtest009" android:duration="100"/>
  <item android:drawable="@drawable/animtest010" android:duration="100"/>
</animation-list>

One Possible way to achieve the desired effect, though not an answer to my question, is to delay the execution of further code by doing something like this:

int duration = 0;
//Add all of the frames together
for (int i=0; i<my_animation.getNumberOfFrames(); i++){
    duration = duration + correct_animation.getDuration(i);
    }
//delay the execution 
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
    public void run() {
       DoYourNextStuff();
        }
}, duration); //delay is here

Edit: There are many ways to solve this problem, the answer given probably does solve the problem I didn't test it, but I ended up just waiting the correct amount of time (at first), then I changed to using an async task (which has a handler method for completion) and ran my animation in the updateProgress call of the async task directly. In the last iteration I am using a threaded surface view to run the animation. This last way is by far the fastest and best (for reasons other then those asked about in this post). I hope it helps someone.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The easiest way would be to post a (delayed) Runnable to the UI thread:

Animation fadeout = new AlphaAnimation(1.f, 0.f);
fadeout.setDuration(500);
view.startAnimation(fadeout);
view.postDelayed(new Runnable() {
    @Override
    public void run() {
        view.setVisibility(View.GONE);
    }
}, 500);

That will do the job painlessly. And never (never, never, never!) try to block the UI thread in Android. If you did so, the phone freezes and you would not see the animation anyway. If you need to wait some time, use another thread.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...