Starting an AnimationDrawable in Android
Asked Answered
L

4

9

Where should I start an AnimationDrawable that needs to animate when the activity is shown?

The developer guide recommends using onWindowFocusChanged, but this isn't always called when the activity is part of a TabHost.

I quote:

It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.

Logical answered 19/7, 2010 at 18:56 Comment(0)
W
6

The parallel thread approach seems to be the most popular one, but it does raise 2 major issues:

  • According to the docs, all UI related code should run on the main (a.k.a "GUI") thread. While calling .start() on an AnimationDrawable might not be considered a pure UI operation, I still feel that it should follow that rule.
  • You can never know exactly when will your animation start. I've seen code with "magic" delay length values that were supposed to fix that. You should know tht God kills a baby kitten every time a programmer takes that approach.

So, I suggest using the very aptly named runOnUiThread() method. Calling it in onResume() will assure you that your animation code will run on the main thread, that it would run after the window is attached, you'd know where exactly the message is about to be processed and no kittens need to lose their lives:

@Override
protected void onResume()
{
    super.onResume();
    runOnUiThread(new Runnable() 
    {
        @Override
        public void run() 
        {
            animation.start();
        }
    });
}
Written answered 7/2, 2011 at 11:57 Comment(0)
S
7

I know this question is a little bit old, but this may be helpful to someone happening across this question like I did. One way that I start my AnimationDrawable's is by creating a new Runnable and using the post method from the ImageView.

You can do like:

ImageView spinner = (ImageView) findViewById(R.id.my_imageView);
spinner.setBackgroundResource(R.drawable.spinner);
spinner.post(new Runnable() {
    public void run() {
        AnimationDrawable anim = (AnimationDrawable) spinner.getBackground();
        anim.start();
    }
});
Stray answered 10/8, 2012 at 21:1 Comment(0)
W
6

The parallel thread approach seems to be the most popular one, but it does raise 2 major issues:

  • According to the docs, all UI related code should run on the main (a.k.a "GUI") thread. While calling .start() on an AnimationDrawable might not be considered a pure UI operation, I still feel that it should follow that rule.
  • You can never know exactly when will your animation start. I've seen code with "magic" delay length values that were supposed to fix that. You should know tht God kills a baby kitten every time a programmer takes that approach.

So, I suggest using the very aptly named runOnUiThread() method. Calling it in onResume() will assure you that your animation code will run on the main thread, that it would run after the window is attached, you'd know where exactly the message is about to be processed and no kittens need to lose their lives:

@Override
protected void onResume()
{
    super.onResume();
    runOnUiThread(new Runnable() 
    {
        @Override
        public void run() 
        {
            animation.start();
        }
    });
}
Written answered 7/2, 2011 at 11:57 Comment(0)
C
0

The Activity's onResume() is always called when the Activity comes to the foreground. Try starting it in there.

Cassiani answered 19/7, 2010 at 18:59 Comment(1)
Doesn't work. It seems the AnimationDrawable is not yet fully attached to the window.Logical
W
0

According to the documentation, you must wait until the view is attached to the window before starting animation. Therefor, you should add an OnAttachStateChangeListener to the view that will execute when it has been attached, and start the animation from there.

ImageView loadingImg = (ImageView)v.findViewById(R.id.image);
loadingImg.setBackgroundResource(R.drawable.progressdialog);
loadingImg.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
  @Override
  public void onViewAttachedToWindow(View v) {
    AnimationDrawable loadingAnimation = (AnimationDrawable) v.getBackground();
    loadingAnimation.start();
  }

  @Override
  public void onViewDetachedFromWindow(View v) {
  }
});
Wildawildcat answered 3/3, 2014 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.