Categories
Android code graphics Java linux Mobile phones programming Solutions

Some things I learned about Android's Frame animation

Hi
Just a quick share of lessons learned about Android’s Frame-by-Frame animations. Some of the functionality is poorly documented, as many people point out, so the web is the only place for answers. Having looked for some answers to these questions and couldn’t find any – here’s what I found out myself.
Update [2/3/11]: A new post on this topic gives a more broad view of my experience.

Resetting Frame Animation

The API is a bit weird here, because the restart function is inside the setVisible function of AnimationDrawable. If you don’t restart and just do another start() on an already finished animation – it will just jump to the last frame. You must reset the animation before starting it.
However if you do setVisible(true,true) your animation will run twice!, so you must do setVisible(false,true);. This will reset the animation for a start() operation.

Preloading Animations

I got to preloading animations after understating that trying to fire an animation “right off the XML”, has a lag of over a second. This must be due to the inflation process. And I was looking for snappy smooth animations right away, without waiting for them to inflate, so naturally I needed to preload them. But how?
So I loaded the frame animation into an ImageView with android:visibility="gone", and “hijacked” its drawable when I needed to fire it:
The XML, just put it somewhere in your main xml so it will be inflated when the app starts.

<!-- Preload animations -->
<ImageView android:id="@+id/anim_preloaded_imgview"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:src="@drawable/myanim"
	android:visibility="gone" />

The Java:

ImageView animateHere = (ImageView) findViewById(R.id.animate_here);
animateHere.setImageDrawable(((ImageView)findViewById(R.id.anim_preloaded_imgview).getDrawable());
AnimationDrawable anim = (AnimationDrawable) animateHere.getDrawable();
anim.setVisible(false, true); //reset! see previous section
anim.start(); //now good to start, even if already fired before

Voila.

OutOfMemory expection? srsly?

So at the beginning I was getting a lot of OutOfMemory exceptions on the loading of the animations. Probably due to loading many big bitmaps into the memory. So I reduced the size of my PNGs to ~80,000 pixels (images are ~200×400), and then I was able to load as many as I wanted! Strange…
I didn’t really research what’s the limit, but using ~140,000 pixels did not fly.
In these cases mogrify is your friend. This will resize all images beginning with “myanim” to 200xWhatever keeping aspect ratio:

mogrify -resize 200 myanim*

That’s it for now
But tomorrow I will learn more. Android is surprising..
Please comment if you [dis]agree, and share your own experience!
Roy.