[GOOGLE LOGO MUSIC] NICOLAS ROARD: I want to go
back a little bit on why did we create ConstraintLayout. So if you look at
ConstraintLayout one, we wanted to have something
that was a very flexible layout manager, something that
would allow you to specify the way your UI should be
laid out and behave in as much of a declarative as possible. And in order to do that, we
created a really rich model of constraints. So you could position
your widgets relatively to one another, you
could central them in between each other. With bias, you have
central positioning, dimension constraint
and ratio, and chains, which is a pretty interesting
way of positioning a group of widgets together. So all of that comes
with a lot of power. And to help you
create those layouts, we also had this idea of
having helper objects. And the helper
objects are objects that are not resulting
automatically in a visual difference
by themselves, but they will allow you to set
up your UI in an easier way. The typical example
is Guideline, where you can create those
guidelines that your designers are so fond of and just align
the widgets to that, which is nice because,
often, before that, you would have to
translate what they meant by guidelines in your layout. Well here, you can simply create
the guideline as in the mock and add things to it. In a similar way, we
introduced the Barrier Helper in the ConstraintLayout
1.1 that gives you some interesting
behavior, where you could decide of a set of widgets
where to position yourself. The other important aspect
on ConstraintLayout, and you'll see that's
going to come in very handy for the rest of this
talk, it's this notion of trying to keep the
view hierarchy flat. So there is some
performance reason for that, but more interestingly,
it's really this idea of decoupling
the layout information, the layout rules to the view
with the view hierarchy itself. And the nice thing with this is
that we have an object called ConstraintSet that can
encapsulate all those rules, and you can create multiple
instances of the subject, swap them in or out
your ConstraintLayout. So that gives you a
lot of flexibility not only to lay out
and create your UI but also at the time when
you want to change your UI. And, finally, it's
an unbundled library. We also from the get
go created this layout to be supported in
the design tools, so we have a pretty
nice UI builder. And that brings us to
ConstraintLayout two. Why did we create
ConstraintLayout two? Well, the key element
here is really to try to create a layout
that is even more flexible. We wanted to give you
back even more power. And we did that in a few ways. One, we added the concept
of Virtual Layouts, which are helpers that will
do essentially a lot of the groundwork for you. So you don't have to manually
set the constraint one by one, you could apply a
set of constraints via this kind of
virtual layouts. We have helpers and
decorators, and also we exposed a lot more of the
internals of ConstraintLayout for you. And that means that you can
do runtime a lot more stuff in ConstraintLayout two. We also did a lot of
work in optimization, and of course a big highlight
of ConstraintLayout two is MotionLayout. It's really the
more flexible way you can think of for
UI is introducing motion and animation. We still continue to strongly
support design tooling, and specifically we are in the
process of building a motion editor in Android
Studio, and we'll talk a little bit about that. And in order to use
it, it's very easy. Just add this dependency
to your [INAUDIBLE] file, and if you're using
AndroidX, similar things, just different naming. Notice we just
released 2.0 beta one. [APPLAUSE] So check it out. We are pretty happy where we
are standing in terms of API, and yes, we are
really looking forward to what kind of feedback
you can give us. So to kind of present
things a little, here is the overall architecture
of ConstraintLayout. We are starting with this
very generic solver that can do a lot of
competition for us and express your layouts
in a very complex way. But we don't expose
that directly. What we expose is
this Constraint Model. The nice thing with this
is that we can in between add an optimizer that takes
care of a lot of situations that are very unambiguous and
don't need a linear solver. So that gives us a lot more
speed in ConstraintLayout two. On top of that, we have
the helpers objects and the virtual layout
that are kind of using this construct model for you. And above all of this,
we have MotionLayout that takes advantage of
this entire foundation. Let me cover a little bit
the ConstraintHelpers. So as I explained,
we did have helpers in ConstraintLayout one. In ConstraintLayout two,
we expose that class. So not only we can continue
to create helpers for you, but you can actually
create your own helpers. So the thing that's important
to notice with the helpers is that they are
not of your group. We are not adding an extra
layer of hierarchy there. All we do is we essentially tag
the widgets with that helper. And the nice property
is that you can actually have multiple helpers
tagging the same widgets. So one widget can
actually have its behavior changed by multiple helpers. But the general idea is that, if
you have a repeatable behavior, you can encapsulate it and just
use it in a declarative way the next time and you don't
have to do code after that. A basic example is
a circular reveal. Nothing too fancy here,
I'm just having a reveal pointing to the different
widget that appears. What's interesting
is the actual code. We are not
reinventing the wheel. It's just a few
animation [INAUDIBLE],, but we are encapsulate
it into a helper, and therefore we can simply
use it in your XML file without having to
do any programming. VirtualLayout is
another type of helpers. And as I mentioned
before, the idea is to still keep
the hierarchy flat. It will position
the widget for you. What's nice is,
because we still are the same level of
the hierarchy, you can reference widgets that
are inside the VirtualLayout and vise versa. So you can also do a lot more
runtime changes on the fly. And let me cover Flow, which is
a virtual layout we introduced recently. Flow supports multiple
modes on helping you layout your objects. The first mode is essentially
creating a chain for you, either horizontal or vertical. And we can also support
different wrap modes. The first one is essentially
still using chains. As we go along, user one is
doing a little more interesting behavior. So this is what it looks like. It looks like a normal widget. We reference other widgets. It's a helper. As a normal widget, you can set
its dimensions, wrap content, and et cetera. And you can constrain
it like any other widget in ConstraintLayout. So it's a very familiar pattern. You can even set
up the background, which is kind of handy
in some situations. And the default behavior, as
I said, is to create a chain. So we do support all the type
of chain-- spread chain, spread inside, backed, and that
allows you very quickly to set up this behavior. What's new is the wrap behavior. It's akin to Flexbox
layout, where if you don't have
the space, before you can offer another space or
you can't do anything else. But, now, we will
create automatically an extra chain for you. By default, we are
using the same type of chain for all the
different chains, but you can actually
specify a different chain between your first chain
and the rest of the chains. You can also set
up a max element before you decide to wrap,
which is kind of handy to create a table like behavior. Or is it? Well, the problem here
is, if the elements don't have the same size,
you're not going to have a grid, because
we'll still have a chain. And that's where the
last mode comes in, where we will align the
elements in the rows and columns for you. So here's an actual
example on how to use it. I'm going to take a UI that
definitely looks like something that could use flow,
a basic calculator, and I want to create the body
of that calculator like that. And the first step is I'm
going to set up the flow, make it wrap content,
center it in the parent, reference the element,
add a couple of attributes to define how it's
going to behave, and we end up with this result. Very easy. You don't have to create
all the changes by hand, all the constraints by hand. You just reference them. What's nice is it's
a normal widget, as it's a normal child
of ConstraintLayout, so you can here
constrain another widget to that flow element
in exactly the same way as you would do normally. But what's even better is
that you can do the same for the inside elements. So, here, you have
this other text view that I actually constrained
on those internal buttons. The other step that we took
to bring more flexibility in ConstraintLayout two is
adding more APIs for you to use. We have the constraint
set API, which is this way of basically
getting the state of the layout. And you can change it and
reapply it to ConstraintLayout. We have a new API, that instead
of you having to manually go and modify the params, we
provide this fluent API that lets you change them and
will do the right things in an efficient way. And there is more. And there is more stuff I'm
not going to cover too much, but we the resize on the
fly, resize handling, state management, we even added
margins on barrier recently. So there is a lot more stuff. But really here what
I'd like to talk about, and I'm going to hand over
to John, is MotionLayout. [APPLAUSE] JOHN HOFORD: So for
those who don't know, MotionLayout is a subclass
of ConstraintLayout. It has a separate XML
file for the constraints and the motion elements
called a MotionScene file. And it allows you
to directly animate between two complete
constraint sets. So the way it basically works
is you have constraint sets, we call them states
internally, and you can transition between them. You can also manipulate the
transition with a key frame, and those can be in a
lot of different areas, and I'll show more. One of the unique
things about the system is it has a few different
coordinate systems. Very important, because
in this sort of situation, you're moving between
two undefined states. The phone could be different. It could be in
landscape, whatever. You need to have a coordinate
system that can handle that. So one of them is
parent relative, another one of them is delta
relative, which is actually the default. It allows you to
move in x and y separately. The other one is
path relative, so if you're deforming
around the path, that allows you to do that. The other thing that we build
is a lot of clever on swipe and on click behaviors. And, actually, in
the beta, there's some new stuff in there
that's quite exciting. So how is it basically laid out? In your layout file, you'll
have your views, your helpers, your virtual layouts,
and it'll point to the transitions, the
constraint sets, essentially the MotionScene file. So let's do an example. NICOLAS ROARD: So
the basic stuff on how you can use MotionLayout
is you need two states. So here, I'm having my little
sun and moving from one state to the other. It's also not super realistic. Typically your sun would
go a little higher. So that's one of the nice
things in ConstraintLayout 2 and MotionLayout is that
you can tweak how you get from the state to the end. It's not just enough to
define those two states, because, often, you want to do
a transition that is not linear. So here, I just want to add,
for example, an arc motion. And I can simply do that
by adding a key position like a key frame that's
going to control the position at the middle of the animation. In a similar way,
often you want to do more than just positioning. You want to change other
types of attributes like here the color. And we can do that as well. So that's where
MotionLayout goes much beyond the pure
layout capabilities. We can charge and interpolate
across a lot of attributes. We have a couple
of extra features that are interesting
with cycles, that's just by separate [INAUDIBLE]
animation as well, you notice that here
the animation is still playing even though we are in
the middle of the transition. And to cover all of that
in more details, John? JOHN HOFORD: So we'll just
go through the main tags. There's KeyPosition position. And, essentially, it
just deforms your path using the coordinate system. And in this case, I pin it to
the complete delta x equal one. Next one is KeyAttributes. You can manipulate rotation,
any of the post layout transforms, you can
do custom attributes with which will reflectively
call all the different APIs. So one of the more complex
things we add is KeyCycles. They allow interactive
animations in space. So, as that the object
progresses, it will animate, and it will just simply provide
a delta in the position. Now, you can apply
KeyCycles to any attributes, so it can be
rotation, and you'll see a whole bunch of
them as we go along. So in this case, as the
animation progresses, it's animating across
the entire scene, which is very different
from KeyTimeCycles, where the animation is
independent of the position. It's sort of setting the
frequency of the animation. And of course, you can
deform these things with lots of clever
shapes and paths and produce lots of
interesting effects. So one of the other things that
we don't really talk about much and I want to mention is
programmatic control here. Essentially, as we animate, we
can make a programmatic change in direction in real time. So what will happen is
you're in an undefined state, because you're halfway
between two states that start in the end. If you issue a command
transition to a new state, it will sort of
recreate a transition between where you were
at that point in time and the new position
that you've requested. So it can be
relatively interactive with your application. We also have commands
that allow you to get the constraints
set involve, and then it's a constraint set. It's an API we've had since 1.0. You can go and change values and
apply it back into the system and rebuild the scene. You can also actually point
to a completely new scene, another XML layout file,
a MotionScene file, and it will just naturally
adapt to that new one. So there are actually a
lot of little APIs in it to allow you to control
things dynamically based on your application. So one of the other
things I want to show is that we can
integrate with helpers. So this is FlowLayout,
as we just talked about. And in fact, all of
these views are in it. But within the
constraints set, you can set the IDs of all the
views that are inside the flow so that you can
change on the fly, and it will animate between
the two layouts dynamically. So you can pop out
views, things like that. So one of the other things
that is pretty important is Touch Handing. It tracks your
velocity of your finger and matches the velocity of
the object you tagged to it. If you leave out an
object to anchor to it, it will just be a percentage
of the screen size. And you can change a
lot of parameters on it about the velocity, how you
want it to terminate, things like that. There are actually quite a few
parameters on the system there. So let's talk a little bit
about the Motion Editor and why we needed to do marble. If you look at what you see
here, in the Motion Editor, you're going to drive
Android Studio crazy. It beats up on in Android Studio
like you wouldn't believe. And unlike, let's say,
a mouse interaction where you're dragging,
you drag and you stop. Someone could leave this
running and go to lunch, and they're stuck. The system has to
be able to handle 60 frames per second
continuous over and over again. And this is something
I just built to show off what it looks
like, what you can do, and here is it in crazy,
because I thought I'd throw it in because it's cute. So now let's actually go through
a little bit about the Editor. We're not going
to release it yet. We're still working on it,
but it's my main job from now until it releases. [APPLAUSE] So this is a copy of
what's right now in Master, and we're running it. So what you'll do is you'll
take a ConstraintLayout, and you'll just right
click and you say convert to MotionLayout, and
then this is what you'll see. You can go ahead and select
a set of constraints, create a collection
of constraint sets for the starting and ending. And then make some
changes on the ending. And, in this case, I just
shorten one of the values, and it animates. That's pretty much it. You can go ahead and
change all the attributes. [APPLAUSE] So it's coming. We are working on it. And I'm hoping, within
the next few months, you'll start to see
versions in alpha. Don't know when. OK, so Nicholas? NICOLAS ROARD:
Yeah, so let's talk a little bit on how you can
actually use MotionLayout in your applications. First of all, all
of these examples are on the GitHub repository
we set up, so check it out. It should be very
straightforward, you have all the examples, all
the XMLs, and all of the code. So how to integrate MotionLayout
with your application? The basic thing to think
of is that you don't have to start from the ground zero. You can start to use
MotionLayout today and integrate it
in your current UI. So here's a couple of examples. If you have a Coordinator Layout
and you have a Collapsible Toolbar, and if you want to have
this kind of animated toolbar, right now it's pretty difficult.
You have to do a lot of code. Or what you can do is
simply take a MotionLayout and use it as a
collapsible toolbar. And you can see on
the GitHub repository, it's really straightforward. You just one little bit
of code to pass over the progress of the
Coordinator Layout, and MotionLayout is
going to do the rest. So that's really democratized
this type of motion. In a very similar way
and very similar pattern, you can go crazy
with a DrawerLayout, or you can make your view
page a little more fancy. Pardon my design skills. And you can use MotionLayout
in a lot of different ways. JOHN HOFORD: So one of the ways
I wanted to highlight today is building a custom components. This actually came from someone
asking about can I do this, and it's like, yeah,
of course you can. So starting really simple. Let's say you just wanted
to have a button that had a little flash to it. You can build a button out of
MotionLayout, do the animation, and decide how it reacts
when you click on it and when you don't click on it. And all these examples
are in just pure XML. There is no code behind
this one in terms of from a user perspective. But you can get fancy in
a bunch of different ways. These are three
different examples I just built up by a few of them. The top one is
interesting in that what's happening there is there
are five different states it can be in. Five different constraint sets. And we have ways to
make it very easy to build a derived constraint
set from another constraint set. So you can derive and
derive and derive. And what you're seeing here
is that the swipe handling is going across all of
the constraint sets, because there is a swipe
that moves you from one to the next to the next. And it all happens smoothly. The second one is simply
a swipe left right, but I added a key
cycle to make it look like the object is rotating. And the third one is
adding some cycles to give you that bouncy effect. I assume you've seen
something like that if you have liked
anything in the past. So I showed you a little
bit of the multi-state. I wanted to
highlight that notice there are five states here,
the one in the center. And I'm swiping across
them or clicking on buttons which transfer them. So you can actually transfer
between all the states, and it all happens
seamlessly, and you'll see that to the extreme
in a later example. So it allows you to have
many different states and do many things very
flexibly with them. It's way too much to actually
go into all the little details that are involved here, all
the different possibilities, but we'll go into that. NICOLAS ROARD:
Yeah, so another way that you can use MotionLayout is
by driving all the components. Like what we've seen
so far is essentially taking MotionLayout and
animating stuff inside it, but kind of like
terminal widgets, right? Well, you can also think about
MotionLayout as something to do Coordinator
Layout would do. And here in that example,
MotionLayout is actually handling the
scrolling of the image but driving this
custom view that's going to get this line going
into a circle like that. So you can easily
drive your own custom views that would have a
specific type of animation and having MotionLayout
act as a scene coordinator. In a similar way, you can
take MotionLayout and put it into another MotionLayout. So we've seen this
at the same example, essentially, with
Coordinator Layout, but that example actually
does the same behavior purely in MotionLayout. And how it works is very basic. You have one MotionLayout,
the outer one, labeled one with
start and end states simply containing a MotionLayout
for the collapsible bar. And we set the progress of
that second MotionLayout from the first one. And the key here is
not so much like we are about to replicate
Coordinate Layout. The key is that we don't know
what your designers are going to come up as crazy
ideas for UI next year or the year after that. So by essentially
having the power of expressing these
type of things, we should be much
more future proof. The other thing is all of
that has absolutely zero code. It's pure declarative
in XML, which is very handy when
you can do that, because it's a lot
easier to change. There's a lot less side effect
to think about than code. But sometimes, code
and programming can be quite handy when you want
to do some runtime behaviors. So let's see how we can
integrate RecyclerView with MotionLayout or take
advantage of MotionLayout in RecyclerView. So I've got my screen
with a basic RecyclerView. And I'd like to be able to
have this kind of motion. I take my element and
just make it full screen. So we can define that absolutely
trivially in MotionLayout, and I define the two states. Very easy. Of course, the issue
is that the position of that element that I'm
animating changes all the time. I don't know where
it is on screen. So you can basically in
the transition listener, you can basically hook that,
get the current constraint set, clear the item,
calculate the new bounds, pass it back, and reapply it. And that's enough for
you to then apply that, and we can use MotionLayout
to animate that element. There's a little more
magic around here, because remember it's
computer graphics. We do tricks all the time. What I'm doing here
is I'm actually making the element
of the RecyclerView being invisible,
recreating the element, putting it in the MotionLayout,
and animating that one. That would ordinarily
be not that simple to do other than the fact that
RecyclerView does exactly that. An adapter in RecyclerView
does just that. It knows how to create a new
view, how to populate it, and it's simply in that
example what we are using. Now, the thing
that is really cool here is not so much
that we can do that, because we could have done
it in a different way. Notice so that I'm
driving that by my finger. So it's not a fire and forget. I'm actually dragging
that element. But because now that animation
is done in MotionLayout in a motion scene XML
file, I can go and tweak it absolutely trivially. So, instead of this
basic animation, let's say that I would
like to delay a little bit the position of that element. I'm just adding this element
in the MotionScene file, and it will just do that. So again, the advantage
of being declarative like that, it gives you a
lot more power and a lot more flexible way of
tweaking your design. And you don't have
to look at your code. It's completely isolated. We can go even crazier. Let's say that I'm adding a
rotation here, because why not. And then you can get this kind
of effect where it's really-- I'm not a good
designer, bear with me. But you get the idea. You have all the features and
capabilities of MotionLayout at your fingertips,
and just go with it. So that example was
interesting, but there is a pattern that
is very common in UI with this kind of infinite list. And for that pattern, we
have an interesting solution. So, when you have a
carousel like that, you actually know
exactly how many elements you have on screen. Typically, you have one. And you may have one
element that comes in, one amount that comes out. But, essentially, the
number of elements that you're playing
with is limited, and more importantly,
you know about them. RecyclerView does that, of
course, but it does a lot more. RecyclerView is going to
compute how many elements you need, it's going to lay them
out, et cetera, et cetera. So I'm not saying don't
choose RecyclerView. But if you have this
type of pattern, we could do something a
little more interesting purely in MotionLayout. So let's do that. If that's my
starting position, I may want to go and swipe on
the right or swipe on the left. And essentially, I
can translate that as different states
in MotionLayout. I have a start state, next
state, previous states. MotionLayout supports
multi states, and we can take
advantage of that. So what do we do with this? The trick here is this
little bit of code. And specifically, that stuff. When I reach the state
next, what I'm doing, I reset the progress to
zero to the start state, and I'm updating my images. So visually, this is
what it looks like. We get that, we go
to the next state, and then moving back
the progress to zero and dating many images. So that's what
happens internally. What you see as the user
is a little more seamless. You have this, you swipe,
and essentially, it looks like the element gets
added back to the new cue. So it's a little bit of magic. But it works really well. And here's a quick example. I have something that looks
very much like a RecyclerView. You notice a couple
of decorators playing in the background, and
you notice that I can just scroll like that. But you've got MotionLayout,
so you can go crazy on the transformation. You can go and add
many more states to it. Here's a quick
other example where it does the same
type of idea but just in a different pattern. So really, what I'm
trying to say here is that you can go much
beyond what we as the Android framework defined for you. MotionLayout is really
a tool box for you to experiment and come
up with something new. So to wrap up this presentation. First, there is a lot of
documentation we put out there. There is the documentation
on developer.android.com. There's various Medium
articles, and we are going to continue to
publish those articles as well. I highly recommend you to check
out the GitHub repository, because there's
tons of examples. And I don't know about
you, but as a programmer, I love seeing examples and
kind of riff off of that. And essentially,
the MotionLayout as part of
ConstraintLayout two, we are pretty happy
with where it stands in terms of the features, which
is why we reached beta one. So I encourage you to check
out beta one, play with it, and give us feedback. We really cannot wait to see
what you are going to come up with that. And again, important feedback. We have a bug tracker,
we look at all bugs, we try to go through them. And the final stuff I wanted
to say about the MotionLayout, as John said, we
put the top priority to walk on Android's
Studio Module to ensure that actually we
have the performances to do a good MotionEditor,
but we are very much intent on shaping that editor
in the next few months. JOHN HOFORD: So if you guys
build any cool examples, share them on Twitter so we all
could see them and enjoy them. I look on Twitter every
day looking for them. So I hope to see some pretty
examples from you guys. Thanks. [APPLAUSE] [GOOGLE LOGO MUSIC]