Introduction to the new Android ConstraintLayout
ConstraintLayout is a new Android layout type presented at the Google IO. It has several new features including a new Layout Editor built in the new Android Studio. (currently on the Canary channel v2.2 Preview 2) The reason for this new layout is to reduce the view hierarchy’s depth and complexity. By using ConstraintLayout, you can optimize and speed up the UI rendering phase of your application. It is compatible with all the currently available Views and ViewGroups and it is part of the Android Support Library. It works down to API level 9.
Getting started with ConstraintLayout
To be able to use the new features provided by this layout you need to upgrade your Android Studio to v2.2 Preview 2, you can do this by changing the IDE’s update settings from Stable Channel to Canary Channel. (File > Settings > Appearance & Behaviour > System settings > Updates) After the update if you create a new project, it will include the layout’s dependency automatically in the build.gradle. If you continue a previous project, you will have to add the following line to your build.gradle:
|layout_constraintTop_toTopOf||Aligns the top of the desired view to the top of another.|
|layout_constraintTop_toBottomOf||Aligns the top of the desired view to the bottom of another.|
|layout_constraintBottom_toTopOf||Aligns the bottom of the desired view to the top of another.|
|layout_constraintBottom_toBottomOf||Aligns the bottom of the desired view to the bottom of another.|
|layout_constraintLeft_toTopOf||Aligns the left of the desired view to the top of another.|
|layout_constraintLeft_toBottomOf||Aligns the left of the desired view to the bottom of another.|
|layout_constraintLeft_toLeftOf||Aligns the left of the desired view to the left of another.|
|layout_constraintLeft_toRightOf||Aligns the left of the desired view to the right of another.|
|layout_constraintRight_toTopOf||Aligns the right of the desired view to the top of another.|
|layout_constraintRight_toBottomOf||Aligns the right of the desired view to the bottom of another.|
|layout_constraintRight_toLeftOf||Aligns the right of the desired view to the left of another.|
|layout_constraintRight_toRightOf||Aligns the right of the desired view to the right of another.|
|layout_constraintCenterX_toCenterX||Aligns the desired view horizontally so that its centers X coordinate is the same as the other views center X coordinate.|
|layout_constraintCenterY_toCenterY||Aligns the desired view vertically so that its centers Y coordinate is the same as the other views center Y coordinate.|
|layout_constraintBaseline_toBaselineOf||Aligns the baseline of the desired view to the baseline of another. Not every view has baseline!|
All of the above mentioned attributes require the ID of the targeted View as the parameter . The class also supports attributes with start and end in place of left and right alignment.
The Layout Editor shows the UI design and the blue print as default. They are always synced together. If you want to change this you have two icons:
Show design icon: You can toggle to show only the design or show both design and blue print. The design view is the same view as were in the previous Android Studio versions, except if you use ConstraintLayout, you will see the constraints on it.
Show Blue print icon: You can toggle to show only the blue print or show both design and blue print. The blue print shows the containing views with their margins, paddings and constraints and if there’s fixed value for them it will be shown.
The editor provides some tools for high level design:
With this button you can toggle to show or hide the constraints on the design and blue print.
You can switch on and off the Autoconnect mechanism, if you drag a view, it will show you the recommended contraints and after you drop it, it will generate them.
Clears all the constraints from the Constraint Layout.
This button activates Inference, which calculates missing constraints for the entire layout.
This button with a number should set the margin of the layout or the selected view (???), but sadly at the time of writing this article, it had no effect on the layout, nor on the xml connected to the layout.
Handles (Tools related to Views inside the layout):
You can grab the edges of the widgets and resize them just like in any other image editor or design application.
Side Constraint Handle:
This control is used to determine where the widget should take place in this container.
Base Constraint Handle:
Align the base lines of the text based widgets. Not every widget has this kind of handle.
Vertical and Horizontal Bias:
Specifies which direction you want your widget to have bias towards. You can specify vertical or horizontal bias.
Restrictions for Constraints:
- You can only connect side handles which are on the same axis!
- You can only connect baseline constraint to another baseline!
- You cannot create cycles with handles!
Widget sizing in ConstraintLayout
It works as the plain old MATCH_PARENT except this one take constraints into account. The guaranteed size is 0dp.
The widget will have a fixed size.
The widget will measure itself and use the smallest size needed for its layout.
Using ConstraintLayout – for Android Developers
In your project create a new layout resource (Right click on “layout” folder > New > Layout Resource file) and in the appearing dialog write ConstraintLayout as the root element, then click OK. The IDE will create the new resource and it will open the new LayoutEditor.
Make sure that the previously mentioned magnet icon, representing the Autoconnect functionality, is turned on. Grab a widget and drag it into the design or blue print. If this is the only view in your layout, you have to drag another one into it. When you are dragging the second view , you will see that the editor will offer aligning it with the first one. After you drop or release the second widget, the editor will generate the last constraint it showed for the view.
Using Manual Constraints
Turn off the Autoconnect mechanism with the magnet icon. In this case you have much more control over the constraints and you won’t have to get rid of tons of unwanted constraints, which would have been generated if the Autoconnect function was active.
- Handles: You can use the handles on the widgets to connect them in order to define constraints.
- Using Inference to create Constraints: Inference is a mechanism similar to Autoconnect, but instead of applying constraints to the dragged or selected view, it will calculate the constraints for the whole layout. To activate this, you have to click on the light bulb icon as mentioned above.
- Deleting Constraints :
- Single: You can delete a single constraint from a view by clicking on the side handle, where the constraint connects to the view.
- All: You can delete all constraints from the layout by using the Clear all constraint function from the toolbar. (“Blue X”, see above)
I ran a few performance tests with a small-medium size layout. During the test, the ConstraintLayout performed really well: it was about 10% faster than the plain old layout based on RelativeLayout and LinearLayout.
The first one uses ConstraintLayout for all of its views and the second one uses RelativeLayout and LinearLayouts.
Thoughts about ConstraintLayout
I know it is still in alpha phase, but there were some bugs and strange behavior I faced while I was trying out the new features.
- If I use centerX or centerY type attributes in the XML editor, I see the modifications in the preview, but if I switch back to the Layout Editor, things get out of sync. The widgets will be drawn according to the XML, but the blue print and the containers on the design won’t be valid.
- I experienced the same “out of sync” problem when changing the views size from the XML.
- Sometimes the LayoutEditor allows Constraints with Handles which will result in an undefined behaviour, it mixes up the widgets….
All together, ConstraintLayout is a really useful tool. It can speed up the UI development and can also produce more efficient layouts. It is really like a RelativeLayout on steroids, which gives you way more freedom than the original. I’m really looking forward to using this in production apps, but it should get to a stable release first. Keep up the good work, guys!