Wednesday, June 1, 2011

Introducing ViewPropertyAnimator

The property animation capabilities that are in Android 3.0 (described in the article Animation in Honeycomb) represent a good building block for powerful animation capabilities in the platform. But we're not stopping there. One minor addition to the platform was added in the 3.1 release, ViewPropertyAnimator. This class allows very easy and efficient one-liner animations of some of the new View properties like alpha, rotation, and scaleX/Y.

Check out the Introducing ViewPropertyAnimator article on the Android developer blog for more about this new API. In the meantime, enjoy this teaser trailer that shows the demo described in the article. The interesting part is the code (shown in the article, not here). And the soundtrack, of course: turn up your speakers.

25 comments:

Nope - no relationship between this (which uses regular buttons and the new ViewPropertyAnimator API) and Renderscript (which is about doing performance- or graphics-intensive operations).For one thing, ViewPropertyAnimator is specific to a handful of properties on the View class, which has nothing to do with Renderscript.You could use the other Animator classes to run animations which changed values used by Renderscript scripts. But this is probably not the best way to use Renderscript, performance-wise - you probably want to stay at the RS level once you're there.

It looks like each call to View.animate() returns the same animator object, which has a single duration, is that correct?

Is it possible to extend the API so that I can specify separate duration for each property? like:

view.animate().x(50, 300).alpha(0, 500);

this would animate x to 50, and simultaneously make it transparent, but the x property would move in 300ms and the transparency would take 500ms. I guess it could still use the same underlying timer, but the animator would know the total animation length is 500ms and it would just interpolate x to complete in 300ms. Is something like this possible as a future enhancement?

@Filipe: Thanks for catching the typo. No matter how many times I edit and revise, there will always be errors. It's like software.

@shez: No, for two reasons. First, it's intended to be a very simple API that extends a simple assignment (x = 50) and makes it an animated assignment. Complicating the API with various optional parameters could end up making it more confusing to use for the very simple cases it's meant to address.

Second, it uses a single Animator internally, which cannot have individual delays and durations for the various properties it's animating. Turning that single Animator into one that knows how to animate individual animations with different attributes severely complicates it, especially when you consider that the different animations would be at different points in their interpolation curves. We'd basically end up creating an entirely new animation system inside this class to handle that functionality.

That's what the other Animator classes are there for. They're not hard to use either, and are intended to provide the flexibility that you need for any animation need. This class is all about simplicity.

@Steve: Actually, the biggest factor in the quality of the demo is the video itself. Between the capture card and the software I used to import/export the eventual screencast, there were a lot of dropped frames that make it seem pretty choppy. It looks way better on my tablet than it does on the video.Enabling hardware acceleration is a good idea in general, just not something I considered for this demo because it wasn't the point I was trying to get across; I just wanted to show stuff moving on the screen.

I didn't watch the video. Just ran it after getting 3.1 on my tab yesterday. Looks better with the flag set when doing the rotation. Probably should be mentioned in the article to get the best results. After the first run, I saw the jagged pixels and almost gave up on it thinking there was something wrong, but then remembered to check for that flag and faith was restored.

Trying to chain animations together, but I see an odd behavior. Say I scalex to 2, that animation ends and I scalex back to 1, that scalex(1) call inside onAnimationEnd triggers an onAnimationCancel on that first animation. Isn't the first animation done once I get the onAnimationEnd? That's confusing. On 3.1 tab.

@Steve: I'll check out the chaining issue, see if there's a bug there. To your earlier [redacted] question: onAnimationEnd() provides a single point through which all animations pass. This simplifies things if you always want to know when something ends (to trigger something else), versus having to implement both and end and cancel listener. If you have special logic that you want to run only on an end, just track whether the animation was canceled prior to the end call.

@Chet: I rewrote all my code to use the ObjectAnimator old api with animation sets to do the chaining. I think that's what I should be using. Using the new API, I could not get the code working to sequentially trigger animations. I couldn't figure out how to handle the cancel state. If I start one animation, then in the end call back start the second, I get the cancel call back and now there doesn't seem to be a way of knowing if that cancel came from starting the second animation, or if it came from the user clicking the button again to start a new animation. Kind of tough to expain, but you could probably make a little modification to your demo to try for yourself. The AnimationSets are better anyway, so not important.

@Steve: I think that's the right thing to do for your situation. VPA was not intended to replace ObjectAnimator, but rather to be an easy utility for animating changes to those specific properties. When you get into more general situations (like chaining animations), ObjectAnimator may be a better choice.I should look into the cancel thing. VPA does auto-cancel prior to starting an animation on a property (to ensure that you're not animating a given property to different values). Maybe there's a side effect there that causes an ended animation to get canceled anyway.

This may not be something that is possible with the ViewPropertyAnimator but i am hoping you can point me in the correct direction.

How would you suggest i go by animating a ViewGroup without animating any of the child views contained in the ViewGroup?

The reason i want to do this is because i want to scale a ViewGroup with an animation and when the ViewGroup reaches a size that is big enough to accommodate another child, one will be animated into the ViewGroup.

@Emil: Yep, that's not a job for ViewPropertyAnimator, which just animates the transform and alpha properties of a View (or a ViewGroup). You should check out LayoutTransition. Take a look at the applications in ApiDemos/Animations that use LayoutTransition to see what it does and how to use it.

Hi there, i was wondering... is it possible to animate width and heigth of a view? I am trying with a LinearLayout, but there are no getter and setter for those value (no luck with LayoutParams as well).Thanks in advance

@Eyahn: width/height are not properties, but rather side-effects of left/right/top/bottom. So if you want to animate the dimensions of an object, animate its left/right/top/bottom bounds. This is what LayoutTransition does when it animates the sizes of the objects that change between the start/end of that layout operation.Note that there is no protection against the layout that an object lives in also changing that object's left/right/top/bottom; those properties are really owned by the layout. So either ensure that a layout will not run during that animation or find a different way to achieve what you want. For example, you can animate the layout params of the object (this is the most correct way to go, although running a full layout every frame of the animation to react to these changes can be expensive).

If I try to create something like Google Music landscape UI Album cover view where a stack of Album pictures can roll from side to side. Does ViewPropertyAnimator API can perform such 3D type of Animator? I tried to search around but there is not much information that talks about how to build such Album view.

Hi Chat. Just wanted to mention that i also run into the described problem when chaining VPA animations. When i scale up and in onAnimationEnd scale down again it works for the first time. When i want to call that chain again, the upscalling does not work anymore.

My question: is it possible to add 'scrollX/Y' animation? When the user taps on particular region of of the full-screen view, the view zooms into that tapped region by using pivot X/Y set to tap coordinates.But if the user then scrolls the scaled-up view and then returns to the normal scale of 1.0f, the scroll values persist - so that the view at the scale 1.0f is shifted (partially hidden).

My Comedy Books

My Programming Books

About Me

I'm a software geek, working at Google, making Android graphics and animation more excellent. In previous lives I've worked at Sun on the JDK, at Adobe on Flex, and various other places in Silicon Valley, always working on graphics software.

In my copious spare time, I write. I write humor on my blog Enough About You... along with my G+ stream at google.com/+ChetHaase and on Twitter via @chethaase. I also occasionally post technical articles on CodeDependent. I co-wrote the book Filthy Rich Clients with Romain Guy, wrote another programming book Flex 4 Fun about Flex graphics and animation, and wrote humor books Round and Holy, When I am King.... and the long-anticipated sequel, When I am King... II. Like women and childbirth, I eventually forget the pain of the process of writing a book, and will probably make the mistake of writing another one eventually. As soon as the scars from the last one heal.

I also have developed a strange and disturbing attraction to the microphone. Any microphone. You may find me giving a technical talk at a developer conference or user group, or doing some standup or improv in a comedy show. I've also been seen in videos ("You may know me from such hits as DevBytes..."), either work-related or posted on my comedy blog and YouTube channel.

None of what I write in my blogs, on Google+, or anywhere else has anything to do with my employer; they're just my thoughts, my jokes, my mistakes.