[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]
