I’m Huyen Tue Dao, and I work on the Android Trello app at Atlassian. I’ll go over Android’s new layout system called Constraint Layout
.
ConstraintLayout
The Constraint Layout is new and was introduced at Google I/O last year. The idea of the Constraint Layout is to give developers a more expressive way of building interfaces. The purpose is to allow the developer to express relationships between views. Constraint Layout is more performant and is much more expressive than Relative Layout
.
Constraint Layout is unbundled from the platform, and it allows two things:
- Support all the way down. You can use Constraint Layout down to API 9+.
- It allows for quick iteration.
How Does It Work?
This Constraint Layout system has three parts.
Constraints
Constraints are relationships to be determined when you set up your UI, namely position, and size (dimensions).
Equations
Once you create these relationships, the system will translate them into a linear system of equations. Based on the constraints you’ve set, the unknowns as to where your views will be, is resolved.
Solver
The solver is called the Cassowary Linear Arithmetic Constraint
solving algorithm. It was developed at the University of Washington. This is the same solver used by iOS’s Autolayout
. The equations go in the solver and it returns with the positions, and view sizes.
Constraint Layout Cheat Sheet
The most basic constraint is an edge constraint. An edge constraint is a relationship between one side of your view to another view. The relationship is one of a target and a source.
If you have an edge constraint on one side and you pair it with the accompanying edge constraint on the other side, this results in a center constraint which pegs a view centered between two targets.
There’s a notion of bias here. In the center constraint, there is a slider on the left and right that lets you indicate space distribution if you want to position something off-center.
Baseline constraints allow you to create a baseline anchor to align different TextViews regardless of their size.
When sizing things in Constraint Layout, you can specify a fixed width, and you can also wrap content. What you cannot do is match parent, as it’ll give you an error. What you should use instead is match constraint in this case.
Guidelines
Guidelines are pure targets for views when creating constraints. There are three types of guidelines:
- “Begin/Start” guideline - which is a guideline that you specify as being offset from the start of the screen.
- “Matching/End” guideline - which is an offset from the end of the screen
- “Percent” guideline - which allows you to specify the guideline’s position from a percentage along the screen.
Guidelines under the hood are views. They’re not rendered and they do not participate in the layout pass. Once you attached views to that guideline and created your constraints, if a margin changes or you need to reposition something, you can grab and move one of the guidelines and all the views will move with it.
Is Constraint Layout Better Than Relative Layout?
Relative Layout always had an issue with performance. The way it resolves its own constraints requires twice the number of measures and layout passes to accomplish what it needs to do.
Constraint Layout, while it’s similar to Relative Layout, expresses its relationships in a “lower level way”, and you see it from the way that the attributes are structured, “I want the start of this one to be lined up to the start of that one.”
In this example, I have a “fab” over a hero view per the Material guideline. It’s recommended that when you have a fab over a hero view, you want the vertical middle of that fab, to be lined up with the bottom of the hero view. This is difficult to accomplish in Relative Layout with only the attributes of “center” and “parent”; this is not granular enough.
With Constraint Layout, I can change the aspect ratio of that hero image and, without anything else, that fab is staying nicely positioned on the edge of the hero view.
Chains, Chains, Chains
A chain in a Constraint Layout is that you have two or more views that are grouped by bi-directional relationships. Bi-directional means that A is connected to B, B is connected to A, B is connected to C, and C is connected to B, forming a chain. The chain gives you a linear group behavior where you can position, have padding, and have spacing. There are different styles of chains:
- “Default spread chain” - where empty space gets distributed evenly.
- “Spread inside chain” - eliminates the spacing at the edges and divides it all up in between.
- “Weighted chain” - it behaves exactly like a Linear Layout with weights, where all those views suck up the extra space into themselves, depending on what the weight constant is.
Constraint Set
The Constraint Set is a class that allows you to programmatically define a set of constraints. It’s much like taking a snapshot or saving the state of the relationships in your Constraint Layout and allows you to create constraint sets on the fly.
There are three different ways you can build constraint sets.
- Build them by hand - the API is pretty large and detailed.
- Create a constraint set by cloning a layout file.
- You can also take an existing instantiated Constraint Layout and clone that.
Constraint Set In Lieu Of Custom Viewgroup
I worked on a lot of Custom Viewgroups when working on apps that mirrored iOS. This can be a chore, and when trying to do something more dynamic, it’s even more difficult. Though Custom Viewgroups can be a powerful tool, it will run into performance issues.
In this example, there is a view with s coin flip (see slides). This was done with constraint set: as you’re clicking the buttons, it’s creating and inflating images and text views, then inserting them on the fly. I have a constraint set that I already cloned from my current layout. I call constraint width and constraint height to set the width and the height, then I need to constrain it vertically and horizontally.
Q & A
Q: At what point does it become overkill? Is there a performance impact for switching to Constraint Layout ?.” Huyen: I usually say, especially when it comes to things like performance, don’t go through a big refactor or don’t try to do anything new and expected, unless you’re having serious performance problems.
Receive news and updates from Realm straight to your inbox