I'm Chet Haase, an engineer on
the Android UI Toolkit team.
00:08
Today, I'm going to talk
about a new animation
00:12
feature in the KitKat release.
00:14
It's called transitions.
00:16
So the idea with
transitions is actually
00:18
the idea behind a
lot of the stuff
00:21
that we do which is trying to
make things easier for you,
00:22
the developers of
Android applications,
00:25
to get richer experiences
for your users,
00:27
hopefully with less effort.
00:29
Transitions, it's
kind of a simple idea.
00:31
It's basically a way for you to
describe the different scenes
00:34
in your application, either
beforehand as layout resource
00:38
files, or dynamically, as things
change in the application,
00:42
and then use transitions to
animate the changes no matter
00:45
what those changes were.
00:48
And you can step out
of the way and just
00:49
let the transitions
run automatically
00:51
without having to
get more involved
00:53
and run these manual
animations which
00:54
are more of the typical model
of animating things in a UI.
00:56
Hopefully, at the
end of the day,
01:00
you get richer
applications experiences
01:01
by having more stuff move on
the screen in an intuitive way.
01:03
Your users get
richer experiences.
01:07
And they get a
better understanding
01:09
of how your application
actually works
01:11
because you can
transition naturally
01:14
between these different
scenes of your application.
01:15
And there's more
animations in the world
01:19
which I'm always in favor of.
01:21
So let's take a
look at some slides.
01:23
And we'll go over a very quick
overview of how the API works,
01:25
what the different pieces are.
01:29
There's a lot of details
that I'm skipping here,
01:31
but you are free and
encouraged to check out
01:33
the details in
the reference docs
01:36
and articles on
developer.android.com,
01:38
and also API demos which
we'll see a little bit later.
01:41
We'll take a look at
some code in that.
01:45
So first, we start out
with the idea of a scene.
01:47
You can think of
this as a layout.
01:50
It's basically a
view hierarchy that
01:52
describes what this
particular scene looks like.
01:54
This could be the scene
of the entire application
01:56
in a particular screen, or it
could be some sub-hierarchy.
01:59
In this particular
case, the scene
02:02
describes this
situation where we
02:04
have a text view, an
edit text, and a button.
02:05
And then we have
another scene that we've
02:10
described through possibly
some other layout file.
02:11
We have different text views
in there, a little bit richer
02:14
text, longer details there.
02:16
But we have, again, an edit
text field and a button.
02:19
And maybe these are
shared components.
02:21
Maybe they moved location,
possibly changed size.
02:23
But they're actually shared
between the two scenes.
02:25
Wouldn't it be nice if you
could help the user understand,
02:28
as they move from scene one to
scene two in your application,
02:31
the changes that had occurred by
fading things out that go away,
02:34
fading things in that have
come into being, and moving
02:37
and resizing the shared
elements between these scenes?
02:40
That's what
transitions are about.
02:43
You specify these
different scenes.
02:44
And then when you go to
a scene, the transition
02:46
automatically kicks in and
runs the necessary animations
02:48
in order to make that
change, as well as
02:52
to animate the change over time.
02:55
So let's take a look at scenes.
02:58
These are the
modules that you've
03:00
defined for your application,
the different screens, if you
03:01
will, of state that your
application will move through
03:04
You can construct these
scenes in different ways.
03:10
First of all, scenes always
have a root or a ViewGroup
03:13
associated with them
which is basically
03:17
the hierarchy under
which the scene lives
03:19
and in which transitions
will take place.
03:21
So you can construct a scene
directly with that root.
03:24
And then you can
set an EnterAction.
03:28
And whenever that
scene is entered,
03:29
you will get a callback
into your Runnable
03:31
and you can run
whatever code, you
03:33
want to make whatever
manipulations
03:34
you want to to the
view hierarchy.
03:36
Fairly straightforward.
03:38
A little bit more manual
than the other ways
03:38
you can create scenes.
03:40
For example, you can create
it from a ViewGroup instead.
03:41
Let's say you have inflated a
hierarchy from some layout ID.
03:44
You have this ViewGroup
sitting there.
03:48
You can create a scene
with that ViewGroup.
03:49
So you give it basically
two ViewGroups.
03:51
You can create with the
root of the scene hierarchy,
03:53
as well as the root
of the scene itself.
03:57
So you pass that in.
04:01
You've created a scene.
04:02
So now when the
scene is entered,
04:04
it will simply change the scene
to be looking at that ViewGroup
04:06
You don't need to
tell it what to do
04:12
to manipulate the hierarchy.
04:14
It gets that information
from the ViewGroup
04:15
that you passed it
in the constructor.
04:17
Finally, we have something
very similar to the last one.
04:19
But instead of handing
it a ViewGroup,
04:21
you hand it a
layout resource ID.
04:23
And when that scene is entered,
it will inflate the resource.
04:25
And it will go ahead and
add that to the scene root.
04:29
The layout resource
also kicks in
04:34
if you create scenes
implicitly in resources
04:36
which we'll see a
little bit later.
04:39
You can have a Transition
Manager that automatically
04:41
inflates scenes implicitly,
given layout resource IDs.
04:44
And it uses the same
mechanism under the hood.
04:48
Next, we can take a
look at transitions.
04:51
These are the engine
responsible for declaring
04:52
what it is you want to
do when things change
04:55
from scene to scene
in your application.
04:58
So these basically listen
for changes before and after,
05:01
and compare those values.
05:05
And then based on changes
that occurred to any view
05:07
in the scene hierarchy,
they'll create an animator
05:09
that then gets run to
animate those changes.
05:13
There's a few different
ways to create transitions.
05:16
You can just create
these things directly.
05:18
We have some defined in
the framework already.
05:20
There's a ChangeBounds
which will move and resize
05:24
objects that change
between scenes.
05:26
There's a fade that will fade
things in and out according
05:28
to whether they come or
go between scene changes.
05:30
And then there's
also a TransitionSet
05:34
which is kind of the transition
equivalent of AnimatorSet.
05:37
It's basically a group.
05:40
It's a way of choreographing
several different transitions.
05:41
You can create a
TransitionSet and then
05:44
tell it whether, for all
of its transition children,
05:45
to run those together
or sequentially.
05:48
And it can also be
a hierarchy of sets.
05:52
So you can have a much
more complicated mechanism
05:54
that runs several transitions
in parallel or one
05:56
after another to get a
more interesting animation
05:59
And finally, you
can load transitions
06:04
from resource files, if
that's the way you go.
06:06
If you want to run
it from resources,
06:09
this is how you can do it.
06:10
This one, for example,
is a TransitionSet
06:13
that gets loaded that has two
children automatically added
06:15
to it to listen for
changes in visibility,
06:17
as well as size and location.
06:20
The resource file,
maybe it's not
06:23
something you want to do from
code because you're already
06:24
It's easy enough to create
these things on the fly.
06:27
On the other hand,
this is the mechanism
06:30
that is used by Transition
Manager when it inflates
06:32
a graph of the information
which we'll see soon,
06:35
but not on this slide yet.
06:40
Finally, there's an idea
of custom transition.
06:42
So we've defined, as I said, a
couple of canonical transitions
06:44
which automatic transition
will use on the fly.
06:48
There's ChangeBounds which
moves and resizes views.
06:51
And there's also fade
which deals with visibility
06:54
information, fades
things in and out.
06:57
Fairly straightforward.
06:58
Probably the behavior
you want in most cases.
06:59
But if you want to define your
own transition-- for example,
07:02
if when something
comes into being,
07:05
you didn't want it to fade in
in the middle of the screen
07:06
where it lives, but
you actually want
07:09
to slide it in from
the right, then
07:10
you can write a
custom transition.
07:12
You would simply subclass
the transition class itself.
07:14
And then you override
the three methods
07:17
that do what it
is you want to do.
07:19
There's two capture methods.
07:21
One captures the values at
the start when the application
07:22
code said, OK, I'm ready
to do a transition.
07:27
That's the point
at which you would
07:29
get a call to your
captureStartValues method.
07:31
And you would go ahead and
just read from the view objects
07:33
anything you wanted to that
affected your transition.
07:37
So you could read the layout
position, for example,
07:40
or the visibility information
that you care about.
07:44
And then you get a call
to the captureEndValues
07:47
when the transaction
actually wants to run,
07:49
when it wants to start.
07:51
And then you finally
get a call right
07:52
after that to the createAnimator
function which can then
07:54
compare those values
and say, OK, well,
07:58
this visibility value changed.
08:00
And that's something
that I care about.
08:02
Therefore, I'm going to
create an animation that
08:04
does the following--
slides in from the right
08:06
Returns that animator.
08:09
And then the transition
system runs it.
08:10
So there's a lot of
stuff that we just
08:12
ship with the framework
for free and you can simply
08:14
use implicitly when
you run a transition.
08:16
But if you want to create
custom transitions, fairly
08:19
straightforward to do that.
08:21
So now you've got your scenes.
08:25
You've got your transitions.
08:26
How do you actually
change scenes?
08:28
How do you go from
one scene to another?
08:29
You could just enter a scene.
08:31
There's no transition
involved there.
08:33
You're basically
just saying, here's
08:34
the scene I want you to load.
08:36
And it will do that.
08:37
It will run the code that
was in your Runnable.
08:37
It will inflate the layout
resource file that you gave it,
08:40
It'll enter the scene.
08:44
Nothing much going on there.
08:45
Certainly no
interesting animations.
08:46
Or you can tell the Transition
Manager to go to a scene.
08:49
And in the process
of doing that,
08:53
it will use a default
transition along the way.
08:55
It'll say, OK, I'm going
to change into this scene.
08:58
And in the meantime, I'm
going to captureStartValues,
09:00
captureEndValues, and run
the default transition
09:02
Or you can run it with
a custom transition.
09:07
You can say, OK, I've defined
this lovely transition
09:09
that I want to
use when I'm going
09:11
between this particular scene
combination, and now go ahead
09:14
and transition using
one of the TransitionTo
09:17
or the go methods in
the Transition Manager.
09:23
And it will actually
load that new scene
09:26
and then run your custom
transition along the way.
09:28
Before we get to
Transitions, Simplified,
09:32
there's one other thing that
I haven't mentioned here
09:34
which is the idea of
a Transition Manager.
09:36
You'll usually use this just for
a one-off thing where you say,
09:38
Transition Manager, I
want to go to this scene
09:41
and use my custom
transition here.
09:43
The other thing
that it can do is
09:45
keep a whole graph
of information
09:46
about all the
transition combinations
09:48
that you want for all
the scene combinations
09:49
that you have in
your application.
09:52
We'll see a little bit of
that in the demo later.
09:53
But I did want to point
out one final thing here
09:56
on this last exciting
slide is that
09:58
with all this information,
all these different classes
10:01
to think about it,
and you've got scenes
10:03
and you got transitions,
but really, the idea
10:05
was to make animations simpler
for most development cases.
10:08
So in general, the only
method that you probably
10:11
are going to care
about is this one
10:14
called
TransitionManager.beginDelayedTransition.
10:16
And then give it the
scene root that you
10:19
want to run the transition on.
10:20
What that does is kicks
in all of the process that
10:22
is going to capture
the current values.
10:25
And then it's going to spawn
a layout and rendering run.
10:28
And then in the
middle of that frame,
10:31
it's going to capture
the end values,
10:33
figure out where things
are, and then run
10:35
an automatic transition for you.
10:37
In most cases, this is all
that you actually care about.
10:38
It's basically a dynamic change.
10:42
You can think of this as
creating and animating
10:44
So instead of having
these pre-baked scenes
10:47
from layout resource IDs,
you can basically say,
10:50
OK, I want you to run a
transition, so get ready.
10:52
And then in the
meantime, I'm going
10:55
to make a bunch of changes.
10:57
And then by the time those
changes have actually
10:58
kicked in, measure
and layout has run,
11:00
and the system is ready
to draw the new frame.
11:02
Then, the transitions kick
in, figure out the deltas,
11:05
figure out the changes,
and create the animations,
11:08
and start the
animations running.
11:10
Fairly straightforward.
11:12
So now, let's take a
quick look at a demo.
11:16
And this is one of the API
demos that ships with KitKat.
11:21
So I would encourage you to
download this from the samples.
11:25
And you can run this
and play with it
11:28
to your heart's content.
11:30
Totally complicated
and interesting demo.
11:31
So we defined four scenes here.
11:33
And the scenes use custom views.
11:36
So no particular reason why.
11:39
These could be buttons.
11:41
I happened to make them
colored rectangles instead.
11:41
So as we change
between the scenes,
11:44
you can see we're
resizing, we're
11:46
repositioning these things.
11:47
And we can just
change on the fly.
11:49
We're interrupting.
11:52
We're running other transitions.
11:53
So fairly straightforward.
11:55
Now let's take a look at
the code for that demo.
11:58
So there's a few
different pieces here.
12:02
First, there's
some layout files.
12:03
So we have Transition Scene One.
12:05
This just has a layout.
12:07
And it has four
views inside there,
12:09
positioned appropriately.
12:11
Transition Scene Two looks
very similar to that.
12:12
It's just different sizes
and different positions
12:16
for the colored rectangles.
12:18
Transition Three
adds the complication
12:19
of also having those gray scale
custom views in the middle
12:23
So nothing really interesting
going on in the layout resource
12:27
But you'll see them referred
to later in the resources
12:31
that we inflate for
the Transition Manager.
12:34
We have some custom
transition that we've defined.
12:36
This is simply a ChangeBounds.
12:40
Nothing really interesting here.
12:42
It's just the
standard ChangeBounds
12:43
that we're going to run.
12:44
But we refer to
this resource later
12:45
when we inflate the
Transition Manager.
12:47
Here's a little bit
more interesting one.
12:50
This is a TransitionSet.
12:53
It's going to run
in the default mode
12:55
where all the transitions
run in parallel.
12:57
It's going to run a
ChangeBounds at the same time
13:00
as it's going to run
a fade transition.
13:03
And the fade is going to be
targeted at a specific view.
13:05
And we use IDs to
associate with views.
13:09
So that means the fade
is not generally applied
13:14
to everything on the
screen, but we're saying,
13:16
hey, I want you to run
this specific transition
13:18
on this specific view
in the hierarchy.
13:20
Fade-out is very similar.
13:22
Although in this
case, it's going
13:24
to run the transition
sequentially.
13:25
So it's going to run the
ChangeBounds on any things that
13:27
change position and size.
13:30
And after that's done,
it's going to run the fade.
13:31
And then finally, we
have a Transition Manager
13:35
which we haven't
really seen yet.
13:37
This is the object that
keeps a graph of what
13:38
you want to happen as you
go from scene to scene
13:41
in your application.
13:44
You can define here-- I mean,
if you don't need any custom
13:45
transitions, then you wouldn't
care about Transition Manager.
13:48
You would just run transitions.
13:51
But if you care that when you
go from scene one to scene two,
13:53
you want this particular custom
transition, but from scene two
13:56
to scene three you
want a different one,
13:59
this is how you would define
it, at least in resource files.
14:00
So you create a
Transition Manager.
14:04
And then you have several
transition objects
14:05
that define the
interaction you want
14:07
in any of these
particular scene changes.
14:09
So we have a fromScene that
refers to a layout file.
14:12
And that's implicitly
going to inflate
14:15
that layout resource file
and create a scene out of it.
14:16
It's going to create a
scene from that layout file.
14:21
And then we have the
transition that it's
14:25
going to refer to in
another transition resource
14:26
file like the ones
that we just looked at.
14:29
So that's all the
resource stuff.
14:32
Now let's look at the code
which is in transitions.java.
14:33
And in the API demos,
you'll see this
14:37
in the Animations directory.
14:39
And it's called
Simple Transitions.
14:43
Not a lot of code going on here.
14:46
We inflate the
Transition Manager.
14:48
Well, we get the
Transition Inflator.
14:50
And then we inflate the
Transition Manager down here.
14:53
And we also create three
scenes along the way.
14:56
And you'll note, we're
only creating three scenes,
14:59
but there were actually
four in the demo.
15:01
And we'll show why in a minute.
15:02
The only reason that we
need the scenes in the code
15:04
here is that this is
where we specified
15:06
they were going to transition
to a particular scene.
15:10
We've already told
the Transition Manager
15:13
what transitions to run
as we go scene to scene.
15:14
And here, we're actually getting
a reference to those scenes
15:17
and saying, OK,
now I want to move
15:20
to scene one, scene
two, scene three.
15:22
And we do that down here.
15:24
When we click on the
radio button in the demo,
15:25
we get a call to
one of these items.
15:27
And we say, OK,
Transition Manager, I
15:29
want you to transition
to the next scene.
15:31
It'll load the scene.
15:34
It'll figure out the changes
and run the transition
15:35
that we specified in the
Transition Manager resource
15:37
Finally, there is a
fourth scene in there
15:42
that has nothing to do
with these scene objects
15:43
But instead, this
is what I referred
15:47
to before as a dynamic scene
because we're basically
15:49
changing the view
hierarchy on the fly
15:52
and having the
Transition Manager
15:54
or the transition
system, in general,
15:56
basically automatically
animate all the changes there.
15:57
We call the magic method,
call beginDelayedTransition.
16:00
We hand it a scene root that
we're going to operate on.
16:03
We call this helper
method called Set newSize.
16:06
And basically, we
make arbitrary changes
16:09
inside the view hierarchy.
16:11
This comes in here.
16:13
It sets some new layout
parameters on the views.
16:13
This will spawn a request
layout internally.
16:16
Things inside the scene root
will end up being relayed out
16:19
And when that happens,
Transition System
16:24
noticed that things
have changed,
16:26
and it runs transitions
automatically.
16:27
As you saw in the demo,
things move around,
16:29
things resize with this
single line of code.
16:32
So that's transitions.
16:37
It's a new feature in KitKat.
16:39
I anticipate it will be worked
on more as time goes on.
16:41
It's fairly straightforward
and simple for now.
16:45
And hopefully, more
importantly, simple
16:47
for you to use to make
richer Android applications.
16:49