[MUSIC PLAYING] NICK BUTCHER: Hello, and welcome
to the last session of Android Dev Summit, or the
ultimate session, I think, which is called Get Animated. My name is Nick Butcher. I am a designer and
engineer here at Google. DORIS LIU: My name is Doris,
and I work on the Android UI Toolkit team. I'm responsible for
Android animation API. NICOLAS ROARD: And
I'm Nicolas Roard. I'm working on the
design tools [INAUDIBLE],, as well as on ConstraintLayout. JOHN HOFORD: John Hoford,
working on ConstraintLayout, MotionLayout, and design tools. NICK BUTCHER: Great. So let's get started. So Android has always
had animation APIs. The number of APIs has grown as
the system has grown and become more fully featured. There are a variety of different
APIs for different situations that have been added over
the different API releases, as well as to the new support
libraries like AndroidX. But sometimes we hear
that the variety-- the range of animation systems-- can be overwhelming,
that you don't know which one to
reach for or which is the best for a
certain use case. So our goal today is
to really give you an overview of the
different animation systems, tell you what they're good
for, what they might not be good for, and give
you the confidence to know which to reach for when
you need to achieve something. And we're going to spend
a bit of extra time on the new hotness that is
MotionLayout today as well. So let's dive right in. First up is Android's oldest
and original animation API, which was AndroidViewAnimation. I would urge you to kind
of consider it deprecated. Unfortunately, it's not
actually at deprecated, as I'll get to in a minute. But maybe just think
of it in that way. So this, like I say,
an older animation API, kind of runs in a certain
phase of the View system. So as everyone knows, most views
have like a measure, layout, and a draw. Unfortunately, because
the animations only run in the draw pass,
it means that we can't do certain things
like deferring rendering when we don't need to. And it also leads
to certain things where because the animation is
only applied in the draw pass, you don't know what it looks
like somewhere in your layout. Maybe you've animated a
button to a certain position. When you try and press
it, the view's bounds haven't actually changed. This only exists within
the view system-- drawing pass system. So it can lead to a bunch
of different problems. Basically it's been
considered deprecated because it has much,
much better replacements. It belongs in a museum. I'd say deprecated except
there are actually-- well, one single use case I can
think of where you still have to use it. And that is when you are
doing window animations. So when you're doing
window animations, when a new activity
launches, then this API only accepts this type
of window animation. Because this existed
from API 1, but also because these windowed
animations have to declaratively state
all the information to perform the animation. The fact that it
runs in a draw pass is useful because it guarantees
that the view is already measured when you do this. And that allows it to
define certain things. Here, we're seeing a y
delta animation, which means 10% of the y position. So because it's already
definitely guaranteed to be measured,
this can be useful. The only other place
you might need to use it is if you're doing
fragment transactions. So here, when you
set the animations to run a fragment
transaction, you can supply this
android.view.animation as an arg. But the API also accepts
the newer Android animator. So I urge you to kind of use
the newer one if you can. So that was View animations. Basically only really use
it for window animations, or if you really,
really have to, if you need to rely on that measured
size part for a fragment animation. Otherwise, I think
it's deprecated. Next up, animator. DORIS LIU: All right. All right. So Nick has just talked
about View animation. Now let's take a
look at the Animator, the new animator API that was
introduced in API [? 11. ?] So the new Animator API is much
more versatile than the View animation because it allows you
to animate more than just view properties. You can essentially use it
to animate any arbitrary property on any object. And you can even just
animate any value-- not necessarily associated
with any property at all-- using the ValueAnimator API. And since the
introduction of Animator, we've built a bunch of
higher-level animation constructs on top
of the Animator, such as AnimatorVectorDrawable,
[? animated ?] [? stateless ?] Drawable, transition, and
the default ItemAnimator in RecyclerView. People always ask me between
Animation and Animator, which animation
API should I use? And the answer is definitely the
Animator API because it's just much more capable. And in this section, we're going
to look at a few animators. We're going to look at
value animators, where you can animate a
value, and we're going to look at ObjectAnimator,
which not only animates a value, but also automatically
sets that value on a property. We're also going to
let animator sets. And then we're also
going to take a look at the ViewPropertyAnimator. It is not an animator, but
it's backed by ValueAnimator. We'll talk a little bit
more about that in a minute. And then also we're going to
look at PropertyValuesHolder, which you can use in
conjunction with ValueAnimator. So here is an
interesting animation with a little juggling man. And that can be achieved
with the double which I think we'll talk about in
the next section or you can use [INAUDIBLE]. But now let's look past that. And on top of this
little man, there are texts being
animated in and out. So in order to achieve
that, we can just simply create a object animator
to animate the alpha property of this view. Pretty straightforward. Notice how here, I'm
supplying as an alpha string. And that is a bad idea because
when the property string is being passed to the
ObjectAnimator, what we're going to do is we have to
prefix that string with a set and get in order to
then use reflection to find the setter and getter
in the target objects class. And that's inherently
more costly. What we recommend instead is
using this view.ALPHA property object. It is introduced in API
14 along with a bunch of other property objects
for other View properties. What happens in
this view.ALPHA is that whenever the animation
value gets updated, the set outlook will be called. And then from
there, the set alpha will be called on the view. So that's one level of
indirection, much more efficient than reflection. If we take a closer
look at this animation, we can see that oh no text
not only animates him, but also it blows up. So there are three
things going on, three properties being
animated-- the alpha, scale X, and scale Y. Here's how we can do that
with PropertyValuesHolder. We can create three
property value holders, one for each property,
and then we can specify the start
value and the end value for each of the property. And once we have all
these property values holders defined, we can then
set these PropertyValuesHolder on the ObjectAnimator. So then the
ObjectAnimator can then drive the change of
the property values. And one caveat is when you
use multiple property value holders on one ObjectAnimator,
you are essentially animating all these properties
with the same interpolator using the same duration
on the same target object. But a lot of times, when
you want an animated scale x and scale y simultaneously,
that's exactly what you need. And if you want to define that
same ObjectAnimator in XML with the
PropertyValuesHolder, it looks pretty straightforward. Now if you take a look at
the bottom of this animation, there is that button fading in
after all the text animations have finished. To coordinate these different
animations together, we can just create
animator sets. And then with a play
method, it would return a AnimatorSet builder. And we want to play the
fade in after the fade out. And then while the
text is fading in, we'll also want to blow it up. So we're going to play the fade
in with the scale animation. And then we want to play
all the text animations before the button fades in. So that's pretty straightforward
API, and powerful too. Now we've seen how we can
animate various properties using PropertyValuesHolder
in conjunction with ObjectAnimator. And if these properties
that you're animating happen to be View
properties, here's a more straightforward
way to animate them. You can just [? call ?]
[? view ?] the animate. That would create a
ViewPropertyAnimator. And then there are a bunch of
methods for various properties. And then you set a end
value for these properties. And then optionally, you can
set an interpolator end start. This is the syntax for
ViewPropertyAnimator. It doesn't get more beautiful
and concise than this. And ViewProperty is backed
by a value Animator. It's not an animator,
so you can't really coordinate it with the
other types of animators. You also can't reverse it
or [? seek ?] or repeat it. Some people ask me, is
ViewPropertyAnimator as efficient as ObjectAnimator? I can assure you it's actually
slightly more efficient than ObjectAnimator. The reason for that is
ViewPropertyAnimator has been optimized for
animating view properties. And as a result, it ensures
that for all the view properties that you're animating,
only one pass of validation gets triggered per frame. Whereas if you
use ObjectAnimator to animate various properties,
then each property change is going to trigger its own set
of your [? validation pass. ?] ViewPropertyAnimator
is more for a fire and forget kind of use
case, where you just start the animation and
just forget about it. Now you might have seen
this animation before in the previous slides. Did you notice that there is
three little dots animating at the end of the text? And since these three
little dots are not really a property for the
text view, so here we're going to create a
ValueAnimator to animate the number of dots. We're going to create a
ValueAnimator of integer type to animate from 0 to 4. And once it gets
to 4, it will then wrap around and restart at 0
because there's a repeat count. And with ValueAnimator,
you almost always want to use an UpdateListener
because ValueAnimator is just going to animate on its own. It has no impact to
anything else [? out ?] So here, with the
UpdateListener, we're going to read the value
out of the ValueAnimator and use it as the number of
dots that we want to show. And then we're going to
have a SpannableString. From the TextView, we're going
to set a transparent foreground color span on the dots
that shouldn't be showing. And with each
animation update, we would update the
number of dots that should be showing, and
then correspondingly change the range to hide the dots
that we want to not show. So to recap, when should we
use what kind of animator? ObjectAnimator is kind of
just all-purpose animator that, as long as you have a
property you want to animate, you can use that. ValueAnimator is for animating
a more customized kind of animation where you
want to animate this value. And then you want to then
use that value to apply it to something else in your UI. And the ViewPropertyAnimator
is best used when you have multiple
view properties that you need to
animate simultaneously on the same view. And because you can't
really coordinate this ViewPropertyAnimator
with anything else, it's only good for the
fire and forget use case. And then PropertyValuesHolder. With PropertyValuesHolder, you
can define multiple properties and then animate them
using an ObjectAnimator. The nice thing about
PropertyValuesHolder compared to ViewPropertyAnimator
is that it not only allows you to animate multiple
properties simultaneously because it's really being
set on the ObjectAnimator. You can then coordinate
that or seek and reverse. So it's more powerful. And then AnimatorSet. When you have
multiple animations that you want to
coordinate, AnimatorSet would be a good choice. NICK BUTCHER: Thank
you very much. Next up, we've got
Animated Vector Drawable. So these are great for doing
vector graphic animations, like these wonderful little
icons you see in the new Google Fit application. Animated Vector
Drawable is actually kind of a very thin wrapper
around two more powerful things. It basically connects
together a vector drawable to one or multiple
object animators and runs animations on them. It has a very kind of
small and focused API. And it basically implements
the animatable interface, which is basically just lets
you play, pause, and stop the animation. So you can get an
Animated Vector Drawable like this and just call start. AVD-- is great for performance
critical and vector graphic animation, especially
from Nougat onwards where Animated
Vector Drawable was re-implemented in native code. And also offloaded
to the render thread, which means that even if
you're janking the UI thread-- and you're not doing that-- that your animation
will keep on playing. But it also means that there's
just more [? rent ?] time on the thread for you to
do your code rather than it running the animation code. So when to use Animated
Vector Drawable? So when you need to animated
icons or animated vector graphics. When it needs to be
this fire and forget because it has that simple
API that just start and stop. And you can't seek through it. You can't control
the progress for it. If you need to do
something like that, then I urge you to take a
look at something like Lottie or Kyrie, K-Y-R-I-E Drawable. So it's really good
for anything which is like performance critical. And that was AVD. DORIS LIU: Thank you. Now physics-based animation. Who doesn't love physics, right? Physics-based Animation
is perfect for a highly interactive use case where you
have lots of gestures going on and you want to then carry on
that momentum of the gesture into your UI to create
the sense of continuity. And because when there are
a lot of gestures in flight, you could then
potentially interrupt the existing ongoing animation. I'm sure you've seen animations
where you want the view to move from one location to the other. And then there is gesture from
the users, and then as a result the ending location
would have changed. And in this case, if you
use Physics-based Animation, that would just simply
change some physics for us. And then as a result,
the course correction would be very smooth. And it also gives your
app a more realistic look. So here I have an example
of this little bubble with my cat's picture on it. And it's in a application
overlay window. So it sits on top of
other applications. And in this case, that is
the beautiful timely app. My goal is as I drag this
little bubble around, I want it to follow my finger. And then when I let
go, it should rest on either side of the screen. So to achieve this,
we obviously need to start with an OnTouchListner. And then we're going
to use velocity tracker to track the movement. And then when
there's action down, we need to record a
bunch of positions. And in the subsequent
move events, we're going to need to calculate
how much your finger has moved since that [INAUDIBLE] event
and then update the bubble's position accordingly. And then when there's
[? action ?] [? up, ?] that's where the interesting
[? base ?] come in. We're going to calculate the
velocity from the Velocity Tracker. And then here, for
simplification for the demo, we're just going to say when
the velocity is greater than 0, we're going to just move to
the right side of the screen, otherwise left side. Now, now that we have the
final position where we want the bubble to rest on, we
can create a spring animation to animate that bubble's
[? parem ?] [? x prop. ?] That is a custom property, which
I'll explain in the next slide. Now, before we
start the animation, we'll also want to set
the start velocity. And this is critical to
ensure that that transition from gesture to the
animation is seamless. So this is my custom property. And the whole point of
this custom property is really just to associate
the animation value with the position of the bubble. Whenever the animation
value changes, we get this set value call. We're then going to set
that animation value onto the [? primes ?] the x
because the view is animating in a application overlay window. And then we're going to have
the Window Manager update View layout to reflect the change. And similarly, in
[? get ?] value, we're just going to return
the [? LayoutFrames.x. ?] NICK BUTCHER: Thank you. Next up is the transitions API. Now transitions are
really about looking at two different layouts
states and saying what has changed
between them and how do I create an animation
to animate those changes. So really you can
think of transitions as like a factory for
creating animators based on those two inputs. A while ago, I might have
stood up here and talked about how it's great for doing
things like this where you can have two different
constraint sets and using Transition Manager. But I think that this
use case is actually better solved by MotionLayout. So I wouldn't consider
this a good use anymore. It does still have some
good things going for it. In particular, this
is probably one of my absolute favorite Android
APIs, Transition Manager beginDelayedTransition. It's deceptively simple,
but you call this, and then you make some changes
to the view hierarchy and magic happens. And that magic is exactly
what we just talked about. It looks at those two
different states of the UI, works out what's changed,
creates an animator, runs those animations. So simple. There is also an
overlay where you can control those transitions. The other thing I really
love about transitions is what it does to the
shape of your code base. So, for example,
here is the change where I moved a bunch of
code out of the View layer and into transitions. So when you're doing
animation, sometimes your code could look a bit
gnarly, like this. So you're doing a lot
of View look-up stuff, [? predraw ?] listeners,
and like poking around to the view hierarchy. By moving it to
transitions, we end up moving it to this much more kind
of like declarative composable architecture. So here I'm using some
custom transitions I wrote-- as well as composed with some
of the framework transitions-- in order to achieve
the same behavior, but in it's more
composable manner. So, yes, you might have to
write some transitions yourself. So here's one I had to
write to do a circular view. But that code ends up being
much more nicer to work with, and much more focused. And I find it a really good
change to the code base. So transitions, when
should you use them? For me, there's actually
one really strong use case, which is shared element
transitions between activities or fragments. So it's pretty
much the only thing you can use to achieve
this, unless you go like super custom. So that is the use
case for transitions. There's actually two
transitions going on here. There's the
[? SharedElement, ?] which is between the two
activities we see here. And then once the
[? DetailsActivity ?] launches, there's actually a window
content transition, which is when the
window launches or when it exits,
run this transition, run these animations
on the content. So when you see it come in
here, when the view arrives, the rest of the content
animates upwards. That's a window
content transition. So when should you
use transition API? So shared elements for me is
a really, really strong use case, window content,
and enter and exit. Also if you're really looking
to like modularize and compose your animation code,
then transitions could be really helpful,
as well as simple changes using that beginDelayed method. So transitions definitely
still have a use case. Motion Layouts. NICOLAS ROARD: All right. So, so far we've been
talking a lot about coding. And the nice thing with coding
is that it's super powerful. You can do a lot of things. The APIs are really,
really complete. On the other hand, it's
also quite time consuming. So taking my hat [? in order ?]
to do [? this ?] [? and ?] [? to ?] [? steam, ?] what
can we do to help that? Really, our goal is to
make you more productive, let you iterate
faster, experiment, and make your life
easier really. So we want to make
[INAUDIBLE] motion. We want to make the motion
design a lot more accessible. So one thing that we introduced
recently in ConstraintLayout 2.0 is the Helpers object. And in fact Helpers
object is something that you've been using if you've
used ConstraintLayout before. That's what we use for
Guidelines, for Barriers, for these kind of tools that are
not really part of your view-- your hierarchy-- in
the sense that they don't show up on screen. But they are here to help
you create those layouts. So to basically bring additional
concepts to make it easier. And in 2.0, we expose
them completely. So you can yourself create
helpers just by [? reaching ?] the class. And what is great
is that it's a way of encapsulating a behavior in
code and putting into a helper. We support the use of
[? first ?] [? in ?] [? order. ?] So it's very easy
to add the widget to those helpers to help us reference
those widgets And you can think about it as a way of tagging
those widgets with a specific behavior. So in this case of
animation, that's really nice because
you get the code, you had your helper built
on top of this code. And we got all the wealth of
the Android animation APIs. And you can do stuff like that. So for example Circular Reveal,
pretty well known animation. The only thing I really
needed to do here is to define this piece of code. And really what
I'm talking about-- what I only need to do here
is this code that you see on the screen,
I'm simply cutting the [? view animation utils ?]
[? create ?] [INAUDIBLE].. So I'm not reinventing
the wheel here. I'm not coming up with my new
way of doing Circular Reveal. But that's the only thing
I need to do for my helper. And then in your
layout file, you only need to declare that
helper and specify the IDs of the widgets
you want to apply to. So it makes basically-- it's a lot easier for you to
package blocks of reusable code and use them in
your application. So going back to the code stuff. So the other way that we thought
about making your life easier, [? young ?] letting you
build [? those ?] reusable [? bricks ?] is by moving to a
declarative way for animation. So you can think about it as
a specification for motion. And we interpret
this specification with a motion engine. And on top of that,
we are building a graphic called Motion Editor. So it's something we
introduced at Google I/O. We are still working on it. We decided to focus those last
few months on the library side [? simply ?] [? implement ?]
this motion engine because we kind of want to make sure
that it's right for you and for your [INAUDIBLE]. Just a quick overview
on the current build. It's coming along, and hopefully
it will come soon in a kind of [? reversion ?] of
[? Android ?] [? Studio ?] But essentially we
want to make sure that the concept in the
library is right before kind of releasing the tool. So that's the overall approach
we have for helping you. So the help out on one hand
and this motion specification on the other. The thing that's kind of nice,
if I look at this in particular is that you can
specify this motion and we'll then take care of it. You don't really have
to write code for it. It's really completely
declarative. So the one way right now that
we implemented this motion spec is through MotionLayout. So what is MotionLayout? It's a View group. So one caveat is that
it means you can only animate the children
of that View group. And it's a surplus
of ConstraintLayout. So if you know
ConstraintLayout that's great. You can directly
use MotionLayout to animate your existing
constraint layouts. On the flip side,
you do have to know how to use ConstraintLayout. But it does a lot. So we do layout transitions. We interpolate
properties as well. We have a really
powerful support for touch-driven motion. So it's kind of like taking
a little bit of values areas of animation and packaging
it into a single place. So roughly speaking, the only
thing you have to understand is we are animating
between two states. We have a start state
and an end state. And we just interpolate
between those two things. So in addition to basically
supporting layout changes-- so essentially we have two
versions of the layout to go from one to another-- we also support
custom properties. So for example, if you
want to animate colors. And we also support the
concept of key frames. And you can think
about key frame as essentially a modifier
on that transform between the start and the end. So to kind of summarize,
we have MotionLayout. It allows you to think
about your animation, your transition, your
motion as a declaration. You just specify what it should
do and we take care of it. It specifically
is great when you want to do fine-tuned
animation-- what we call like bespoke motion. It's very specific
what you want to do. It's about coordinating
a bunch of widgets together in a very specific way. And finally, it's
really nice as well for the touch-driven motion. JOHN HOFORD: I don't
think I need the mike. So I want to just kind of like
show you guys a lot of things. And it'll be a little more
visual from here on in. So this is where you want to
create a carefully crafted, custom, coordinated, crazy
cool animation that you could do stuff like that. So how did we do that? It's just two chains that
change into one chain. And each letter is a view. And then we use a stagger and
a color change and a custom attribute. It's fairly simple to build. It took me a few minutes,
and it looks cool. And that's kind of what
this stuff is all about. So the first thing, you can
drag our stuff with touch. Essentially it
will handle swipes. If you flick, it will
go across quickly. It understands the
velocity and manages that. The next thing to
understand is we're starting from two constraint
sets, but we have key frames. And in this case here, I am
starting with two constraint sets and I'm not
having any key frames. And you see how it
crosses right there. Right there they overlap. So what you do is you add
some key position key frames, and you accelerate in the x. You finish the x part of
the motion halfway through, and that gives you
a kind of smooth-- you've seen this. It's your Settings menu. So the more extreme end of
what we can do with key frames are key cycles. And here you can see a bunch
of different kind of effects that we can do. Essentially, anything that's
oscillating-- it's shaking or it's bouncing around. You don't want to
actually go and build out complex paths with key frames. This solves it. And then in alpha 2 we
introduced time cycles. And this is a kind
of a crazy animation that you can do with it. Of course, this is
way too over the top, and please don't
use this in product. So let's get into how to use it. NICOLAS ROARD: Right. So thank you. So first of all, there is
a bunch of documentation that we created. So I'm going to pass
quickly, but please look at those article. There's also a GitHub with
examples, so look at that. But one thing you
may ask yourself is that, OK, this is all great. But how do I use that
in my application? Do I have to restart
everything from scratch? Not quite. This is an example here where
you have a collapsible toolbar and a CoordinatorLayout. And to do these kind of things
with the normal collapsible toolbar is a bit annoying. You have to do it in code,
et cetera, et cetera. You can simply use
MotionLayout instead. So you still use
CoordinatorLayout. You don't really change
anything else in your code, but the collapsible toolbar
becomes a MotionLayout and take all the
advantages of it. Similarly, if you
have a DrawerLayout, you don't have to use
them in your [? class. ?] You can use a MotionLayout
for it and do anything crazy. Same thing for ViewPager. You can easily plug
MotionLayout into it. The last example is interesting. It really looks like
CoordinatorLayout. But actually this is
pure MotionLayout. And what's nice about
it is that it actually is two MotionLayouts nested. And we have one for the
collapsible toolbar. In fact, it's exactly the
same one I used before for the [? conduit ?]
[? layout ?] example. And it's simply nested into
an [? outer ?] MotionLayout. And what's really
nice is that in order to specify how this
overall screen behaves, I just need to create those
two states, the start and end. You see that in the end
I bring up a [? fab ?] and I simply make the
MotionLayout that's for the toolbar
a little smaller. And basically we take
care of all of it. So to summarize for
the current states, we are still working on
the graphical editor. But for the library, we released
it already at Google I/O. And since then we did an alpha
2 with a few more properties. And even [? putting in ?]
alpha, it's actually built upon
ConstraintLayout 1.1. So it's actually pretty stable. And in fact, because
it's pretty stable, quite a few people started
to build stuff with it. And we'll go through
some examples just to give you a
little taste of what you can do with MotionLayout. JOHN HOFORD: So I looked
on the Twitter a lot. I checked MotionLayout
on Twitter all the time. And I thought I would just share
a few interesting animations that people have published. So most of these you can
actually find in GitHub. These people publish
them as videos, and I've asked all of
them to sort of show them. This guy has been doing quite
a few pieces of work with it. It's kind of interesting
to see what he did here. NICOLAS ROARD: And this one
is particularly interesting. By the way, [? we did ?]
[? not ?] maybe notice in the previous one, there was
a [? knock ?] [? motion ?] which is very nice, something we
[? didn't ?] [? refer ?] to. But in this particular
example, what's nice is that it's kind
of like a [? View ?] He did it in
MotionLayout, but he also added a way to
drive it from code. And that's a very interesting
future avenue for us. We're going to explore
it a little bit. How can you, in code, reuse
some of this previously defined behavior? JOHN HOFORD: So
another one by him. The interesting
thing here, it's sort of mixing what is a normal
RecyclerView and then sort of a reveal detailed view. But it's an interesting
MotionLayout based animation between the two of them. NICOLAS ROARD: And
you notice that it's super easy to come up with
your own ways of doing these kind of transitions. You're not limited anymore. JOHN HOFORD: This guy
implemented a material design automation spec, but just
using MotionLayout and a custom view that he built. It was quite
nice piece of work actually. One of the things I liked about
this one is it's so original. You see a [? View ?] pages. This is like taking a
whole new twist on it, or spin on it actually. But you could see its original. And that's the beauty
of a MotionLayout. You can sort of explore
your own creativity or your team's creativity
with what they like and what they do. This one is interesting
because it's kind of like a typical
CoordinatorLayout stuff. But you see it's
transparent, and there's some special effects
going on with things fitting in as it's collapsing. It sort of produces a unique
Custom View of the whole thing. And this is our Chris Banes. And he did a very
interesting one. And it's a whole app. It's actually all the codes
involved that is out there. And it is very custom. So let's take a little
closer look at it. NICOLAS ROARD: So
what's great with it is this is the type of
motion that would be kind of [? fun ?]
to build purely by code because there is a lot of
subtle coordination across so many elements. The text is fading. That poster is actually
rotating but actually matching the [? young girl ?]
of the [INAUDIBLE].. So that's what we
mean when we are talking about bespoke
motion, or very fine-tuned, custom crafted motion. This is the type of
example that we hope will encourage you to build. JOHN HOFORD: And as
a small sneak peek at what we have in alpha 3, it
will support multiple states and allow you to interact with
the multiple states purely from touch. So this is one
single MotionLayout, but in fact it is
handling transitions between three transitions-- from a blank page, to
swiping up the bottom, to swiping a little
bit, to swiping more. It's all one-page,
one MotionLayout. And it can produce a fairly
sophisticated custom view. And I sort of made it
look like a [? dialer. ?] NICOLAS ROARD: And [? decent ?]
behavior, or this touch behavior, 0 code from your end. It's all declarative. [APPLAUSE] NICK BUTCHER: Pretty awesome. Cool. So today, well,
hopefully we've given you a guided tour through this
variety of animation APIs that does exist on the platform. And our goal was really
to make you more familiar with what they're good at and
what they're not so good at. So I'm trying to summarize
that as a takeaway for you here so that you are confident
in picking the right one at the right time. For complex coordinated layout-- and especially for that
nice handoff between gesture and animation-- then really,
really, really do check out MotionLayout. Next up, if you need to build
interruptible animations or, again, do gesture to
animation with that velocity tracking, then look at
the physics layout system. If you need to do shared element
transitions or window content transitions in your
application, then Transitions is the API for you. And if you need to do
vector graphic animations, then check out
AnimatedVectorDrawable. If you need to do
window animations-- and only if you need to do
window animations-- then the original SDK 1.0
View animation system should be used. It's your only choice. If you need to animate
properties of views and it's supported
by it, then look at the ViewPropertyAnimator. If you need to do custom
view animation or some custom thing driven just by
an animation pulse, then look at the ValueAnimator. And lastly, like else,
use ObjectAnimator. ObjectAnimator is
your go-to default for general purpose animation. So hopefully that's
made it a bit clearer. So next time you have
to build something, you won't be paralyzed by choice
of the different animation APIs. So thank you very
much for joining us. And we'll be outside
for questions, or contact us online. Thanks very much. [MUSIC PLAYING]