DevBytes: Property Animations

DevBytes: Property Animations


[TYPING SOUND] Hi. I’m Chet Haase, an engineer on
the Android team at Google. I work on graphics and
animations, and today, I want to talk about the new animation
system that came on in the 3.0 release. Specifically, I want to talk
about ObjectAnimator and its ability to animate
view properties. So, let’s take a look at a demo,
which looks remarkably similar to a demo we saw in a
previous episode where we were talking about View Animations. So the point of today’s demo is
to show basically how to do similar kinds of things with
the new animation system as you could do with the old
animation system. So we have some very boring
buttons on the screen with names of animations that are
going to run on the buttons as we click on them. So we have an Alpha Animation
that fades the button in and out. Translate moves the
button around. Rotate spins it around. Scale, and then Set runs the
animations in sequence. Now, one thing to note about
this demo versus the View Animation demo is that you can
use the choreography class called Animator Set to actually
run different animations on different
objects. It’s easier to choreograph more
complex animations where this animator set is actually
running animations on several different objects, not just on
the same button down there. Regardless, they’re kind
of ugly animations. This is not what you’d want
in your application. This is a little bit more
about the technique of creating and running
these animations. Also, just as in the previous
demo where we saw View Animations created from
resources, you can also create Object Animator animations
from resources as well. So we check the little box, and
we can load and run the animations that are
then created from resources instead. On this one, the animation
resource is actually running on the same button, so we get
that really egregious effect of running as animations
in sequence on that single button. Demo, not terribly
interesting. Code, a little more
interesting. So, let’s take a look
at the code. So we have this class called
Property Animations. We have the check box that
controls whether we’re going to be loading from resources
or loading from code. We have the buttons that
we create here. We’re loading from the resource,
the layout resource, and then we have the
animations that we create on the fly. So this is sort of the general
way of how you create object animators to animate specific
properties on views. Let me bring this code a little
bit more in line so you can actually see it
on the screen. So we have an alpha animation. This is created by saying,
OK, I want a floating point animation. There are all these factory
methods on Object Animator as well as Value Animator to create
and then return one of these animator objects. So we’re going to say object
animator dot of float, and the target of the animation is going
to be the Alpha button that we found by ID above, and
we’re going to animate the property view dot alpha. Now, there’s different
ways to do this. The original way in 3.0 was to
actually use a string where you use a word that is then
associated with setters and getters on the target object. So in this case, we could use
the string “alpha,” and then it’s going to use reflection
or JNI to go in and look at that target object you provided
and say, is there a set alpha that I can call
during the animation? And optionally, it may also look
for a get alpha to derive the original value that
it starts from. But in I think it was 3.1 or
3.2, we released a new property mechanism which are
these static objects on the view class itself, and they’re
slightly more efficient. So instead of using reflection
or JNI to get to the setters and getters, we can simply call
directly into a setter and getter directly in
the property object. So, slightly more efficient. I tend to prefer that when I’m
animating view properties. So we said, OK, I want to
animate the Alpha button. I want to animate the alpha
property on that button, and I want to animate it to
a value of zero. Note I didn’t tell it what
value to start from. It’s going to assume that it
starts from whatever value it has right now. So it’s going to go ahead and
call the property object and say, what value do
you have now? Now, animate it to zero. It has a default duration. Unlike the old animations, which
didn’t have a default duration, the new Object
Animator animations have a default duration of three
milliseconds, so we don’t need to set that duration. We’re going to set a repeat
count of one, which means we’re going to run once and then
repeat once after that, and a repeat mode or reverse, so
it’s going to fade out and then back in. Translate animation– similarly, we’re going
to create an Object Animator of float. We’re going to target the
Translate button, and we’re going to target the View
Translation X Property and give it a value of 800. So this means it’s going to
start from wherever it happens to be right now, which I
happen to know is zero, because I wrote the app, and
it’s going to animate to a value of 800. Repeat count of one, a repeat
motor reverse, which means it’s going to animate over the
right, and then slide back over to the left. Rotate animation. You’re probably getting
the pattern by now. We say object animator dot of
float of the target that we want to animate and the property
on that target we want to animate. We’re going to animate from
its current value, which happens to be zero,
to a value of 360. So it’s simply going to
spin a full loop. And by default, it’s going to
rotate around its center, and you can set the pivot point
for scale in rotation animations. Repeat count of one. Repeat mode reverse, so it’s
going to spin, and then it’s going to spin back. And then we have a slightly more
complex one for scaling, because we’re going to animate
two properties at the same time, the scale x as well as
the scale y, so we use this other the class called Property
Values Holder, and say, I’m going to want a
property values holder of float, and we’re going
to target these properties on the object. And we’re going to scale up from
whatever it happens to be, starts with the default
value of 1 up to a value of 2. Then we create a scale
animation, and instead of being of float, we’re going to
say of property values holder. That’s the target object. These are the property value
holder objects that we’re going to use, and again, we’re
going to repeat and reverse. Finally, the set animation. This uses the animator set class
which provides an easy way for you to have more
interesting choreography of multiple animations. They can be staggered in time,
or run together, run sequentially. Lots of different ways
to use this. One of the things you’ll note
is that there’s this fluent API where you can say, I want
to play the translation animation, and I want to play
that after the alpha animation but before the rotation
animation. Sort of build up these complex
chains, and then you start the animation. It figures out the tree, the
graph, of how these things interrelate, and then it
executes all of them in the order that you specified. Then we call the setup animation
which says, OK, here’s the objects that
we created above, and alternately, here’s the resource
IDs if you want to run it from the resource
instead. So we go into that method where
we set up and run the animation, and if the check box
is checked, then we need to load the resource first. And this is something
to be aware of. If you are going to use animator
resources, they don’t have a concept of instances in
the resources, so after you load the resource and you have
your animator object, then you need to set a target on it so
that it knows what target you’re actually trying
to animate. So we’re going to set
the target, then we start the animation. Alternatively, if we’re not
launching from the resource, if we’re not creating from the
resource, if we’re instead creating from the codes that we
had above for creating the animations, then we simply
call start on that. Let’s take a look at some of
the resources for how we create these things. We have an object animator tag,
and we pass in property names which should make sense. They were sort of created
that way. So we have a property name. We’re going to animate alpha. We’re going to repeat it
once and reverse it. Duration of 300 milliseconds,
and a value to zero. So it’s simply going to fade
out, and then since it’s reversing, it’s going
to fade back in. We have a move animation,
again, similar to what we saw in code. Scale animation. This one is the one that
actually has two properties that are being animated
in parallel. Instead of using property values
holder, I happen to be using an animator set here where
we create two object animators on the different
scale x and scale y properties. Spin is going to do a
rotation animation. And then finally, this combo
file is an animator set which is going to run all of these
sequentially, and it’s going to run it all on the same
target object there. So this is the new Property
Animation system. So if you’re running code from
3.0 onwards, it’s a more robust animation system where
you can target these view properties as well as any
arbitrary target and arbitrary property, and we’ll see some
of that in future episodes. Thanks.

14 thoughts on “DevBytes: Property Animations

  1. How would you go about supporting these animations in 2.3? Or what would be the best way to gracfully degrade these so that it doesn't crash in 2.3+?

  2. I'm an android beginner and I don't understand how you can create all your animations in the oncreate and pass them to the onclick without having to redefine your variables. Could you expand on that?

  3. I have a button:
    final Button button1 = (Button) findViewById(R.id.button1);
        
        
            ObjectAnimator anim = ObjectAnimator.ofFloat(button1, View.TRANSLATION_X , 800);
            anim.setRepeatCount(1);
            anim.setRepeatMode(ValueAnimator.REVERSE);
    No errors show. but the button will not move

  4. Is there a reason, other than style that you used PropertValuesHolder for the scaling animations rather than an animator set with scaleX and scaleY separately?

  5. At 3:15, he says it will use Reflection or JNI. I get that it uses Reflection to find setters and headers but why and when would it use JNI? Does it have something to do when using Hardware layers or?

Leave a Reply

Your email address will not be published. Required fields are marked *