What's new in ConstraintLayout (Google I/O'19)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[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]
Info
Channel: Android Developers
Views: 31,371
Rating: 4.8885245 out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Google I/O, purpose: Educate
Id: 29gLA90m6Gk
Channel Id: undefined
Length: 35min 2sec (2102 seconds)
Published: Thu May 09 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.