Tuesday, April 22, 2008

Animated views

I have to admit, I am aesthetically challenged. Creating a nice GUI is not my game and I respected those who could design such things. Because of this limitation of mine, I generally look down on glittering UIs with contempt. But even I was moved - even if only a bit - by Android's animation capabilities.

Android is able to animate any View object and each and every View has a startAnimation() method that launches animation. Animations exist as independent objects that can be applied to the Views. Animation objects can even be populated from XML resources that live in the res/anim directory.

You can download the example program from here.

Let's look at the animation file below (again, XML mangling due to the limitations of the blog engine). This file can be found as res/anim/magnify.xml in the example program bundle.

[?xml version="1.0" encoding="utf-8"?]
[scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.5"
android:toXScale="2.0"
android:fromYScale="0.5"
android:toYScale="2.0"
android:pivotX="0%"
android:pivotY="50%"
android:startOffset="0"
android:duration="400"
android:fillBefore="true" /]

This is a scaling animation. The attributes mean the followoing:
  • The content of the view is actually shrinken first (fromXScale, fromYScale=0.5) to half before it starts to grow to double its standard size and 4 times of the initial size (0.5->2.0). This is done both in X and Y axis.
  • The pivot point from which the object grows is 0% in the X axis. This means that the leftmost points of the object will stay in place and the object grows rightward to double size. Meanwhile, the pivot point on the Y axis is the middle of the object (50%), this means that the object will grow up and down from its center line.
  • The animation starts immediately (startOffset=0) and finishes in 400 msec.
Once we have an animation object, we can apply it to any view. In the example program, I created a simple list and applied the animation to the TextView list elements whenever one list element is selected (either by moving the selection with the arrow keys or clicking at list elements). Two points are worth noting:
  • Just because we animate, the list layout is not recalculated. Hence the generous top and bottom paddings around the list elements. There is enough space provided for the TextView to grow.
  • In the list row layout (res/layout/row.xml), the layout_width is set to fill_parent. This is seemingly random choice but actually, the program does not work well with wrap_content as layout_width. Whenever a list element is selected, its color changes to highlight. If the width is wrap_content, then the size of the TextView (hence the higlighted screen area) is just the length of the text. When the animation starts, the text grows past this size and the end of the text becomes unreadable. This is very important therefore to allow the list row to occupy the entire available width because then the entire row will be highlighted and the animation cannot grow larger than the highlighted area.
At last, two pictures about the beginning and the end of the animation.


19 comments:

Damien said...

Nice one. 40 seconds after examining your code I had button animations in my app. Very informative.

D.

Gabor Paller said...

Take care, animation requires CPU activity and therefore battery power. Use it with reservation. :-)

North Sun said...

Very Useful information...thanks

Maxon said...

Very simple and useful post!
Thanks!

Hafiz Muhammad Zeeshan said...

Thanks for the post, it is really usefull

Elad Katz said...

what happens if i want to animate an imageview to make it move?
I want to be able to make an imageview move from point a to b
while going through several different views.
For example, say I have a table layout, is there any way an imageview
can move from the topleft cell to the bottomright cell?
Everything I tried seems to indicate that an imageview will only be
shown in it's own container - none of it's parents, siblings or
children will show it.
Is that correct? is there any way around it? like creating an overlay
or a transparent canvas on top of the entire thing so I can do it?

DIEGO FABIAN GALLEGO FERNANDEZ said...

Hi, I need change the position of my ImageView (x,y) when I click over it. Plz Help me.

Dittimon said...

Fantastic! Thanks!

VISHNU said...

is it possible to flip animation in android ,like i phone...?
please post code.....
sunke.premsagar@gmail.com

Sagar Dutta said...

Cool articles.....
helped me a lot on my android journey..

Andrijana said...

fantastic........

smritipathak said...

very nice tutorial....thnx

Anonymous said...

Thanks, fast and useful.

saurabh daga said...

i am new to android ... so do not know how to put this in my code.. i basically first created a folder in res named anim and then i made an xml file named magnify and put your code there but gives me an error ..


please help me out...

Gabor Paller said...

saurabh, download the test program (link is in the post) and just copy the relevant parts into your program.

Anonymous said...

really good post...

Anonymous said...

GREAT

wonderful description. Took me a minute to create my own scale animation.

naved anjum said...

hi,
I am a new android developer,i just want to animate an image by touching on it in only y-axis.
please Help me.

Gabor Paller said...

naved, what is the problematic part? The touching or the animating?