Constraint layout was introduced to solve alignment and performance issues of previous layouts. It is similar to relative layout in that widgets are positioned relative to siblings or parent. But it is more flexible meaning it allows you to easily align widgets as required and create responsive layouts. You can create layouts fast with improved runtime performance.
You can create constrain layout by either editing xml or using android layout design tool.
In this post, I’ll explain features, all properties of constraint layout, and how to use those in xml and in design tool.
Speed of development, performance of layouts, responsive layouts are some of the features of constraint layout.
One of the issues with other layouts is that using them leads to increase in hierarchy levels. Nesting layouts is a problem because rendering nested layouts take more time compared to flat layouts. With constraint layout, you can create flat hierarchy layouts there by improving the rendering performance of layouts.
Constrain layout allows you to build layouts which behave in terms of display as designed on the devices with different screen sizes. Constraint layouts are responsive because of the position constraints and ability to set the size of widget to match to position constraints.
You can create constraint layouts fast with easy to use android layout editor tool which was re-created to support constraint layout.
Constraints determine the position of a widget in layout relative to other widgets, guideline or parent. Here guideline is a vertical or horizontal line, used to position widgets relative to it. Guideline objects are not visible on the screen at runtime.
If you add a widget to layout without any constraints, it will be positioned top left corner of the screen.
Now let’s add a constraint to make a widget positioned to top right corner of the screen. For this, we need to constrain the widget to parent meaning constrain the right edge of the widget to the right edge of parent. In xml layout file, you can set attribute layout_constraintRight_toRightOf to parent or use layout editor like below.
To position a widget to bottom edge of parent, set attribute layout_constraintBottom_toBottomOf to parent. To do the same in layout editor, select the widget and pull bottom constraint handle to bottom edge of the parent.
Similarly, to align left edge of a widget to left edge of parent, use layout_constraintLeft_toLeftOf attribute and to align top edge of a widget to top edge of parent, use layout_constraintTop_toTopOf attribute.
If just left edge of a widget is constrained to right edge of parent by setting layout_constraintLeft_toRightOf attribute to parent, it will not have any impact on alignment. Similarly just usig layout_constraintRight_toLeftOf, layout_constraintTop_toBottomOf, and layout_constraintBottom_toTopOf constraints, will not have any impact on position of the widget.
But if you add two constraints for a widget on the same axis and to the same side of a target, the constrained widget will be positioned to center on that axis if target is parent otherwise half of the widget which is constrained will overlap the target widget to which it constrained. For example, setting layout_constraintLeft_toLeftOf and layout_constraintRight_toLeftOf constraint attributes to parent will make the widget positioned to center on x axis.
To position widgets properly in constraint layout, you need to add at least one horizontal and one vertical widget.
You can add baseline constraints to horizontally align texts of two or more views. The attribute that is used to align text baseline is app:layout_constraintBaseline_toBaselineOf. Below is an example to show how to align baseline of text of two views in layout editor.
You can add horizontal or/and vertical guideline to layout and add constraints to views against guide lines. Guide lines are not displayed as part of UI at runtime.
Using guide lines, you can not only align views vertically or horizontally, but also aligned views can be moved together to adjust vertical or horizontal alignment point by moving guide line.
If two sides of a view are constrained on the same axis, the widget will be positioned center between the two constraints. In this case, layout editor shows constraint line differently as shown below.
Position of a view between the two constraints on the same axis can be controlled by a property called bias.
By default bias is 50%, which is why view is centered between two constraints. You can change bias in the properties window or in the editor by dragging the view. The two bias constraint xml attributes are layout_constraintHorizontal_bias and layout_constraintVertical_bias.
The space between two sides of a constraint includes margin. In the layout tool, you can adjust default margin. Default margin is applied to all constraints.
The space for bias excludes margins. Below picture shows 8 and 64 margins and rest of the space is for bias setting.
Xml attributes for margin are android:layout_marginStart, android:layout_marginLeft, android:layout_marginTop, android:layout_marginRight, android:layout_marginBottom.
There are other margin attributes which can be used to set margin for a view when constraint’s target view visibility is set to GONE. Those margin attributes are layout_goneMarginStart, layout_goneMarginEnd,layout_goneMarginLeft, layout_goneMarginTop, layout_goneMarginRight, and layout_goneMarginBottom.
Dimentions of a view can be set using android:layout_width and android:layout_height attributes. Similar to views in other layouts, you can set dimensions to fixed size or to wrap_content. In constraint layouts, views dimention can be set to MATCH_CONSTRAINT meaning height or/and width is set to 0dp.
If width is set to 0dp, view will be expanded horizontally to occupy space between the constraints excluding margins. If height is set to 0dp, view will expand vertically. In below screen, all three button’s width is set to 0dp.
You can set width or height of a view as ratio of other dimension. The attribute layout_constraintDimensionRatio is used to set size ratio. This attribute is applicable or can be used only when either width or height or both set to match constraint.
For example, width of a view is set to match constraint (0dp) and you want height to be 3:2, then setting would be app:layout_constraintDimensionRatio="h,3:2". The first button in the below picture has this setting.
In the below image, second button width is set to match constrait (0dp) and app:layout_constraintDimensionRatio attribute is set to "w,5:2".
If you want to remove one constraint of a widget, just click on the constraint handle.
To clear all constraints of a widget, select the widget and click clear constraints button as shown in below picture.
To clear all constraints in constrain layout, click clear all constrains button as shown in below picture.
Views can be linked to each other bi-directionally to form chain of views. To create a chain, add views to layout, select all views, right click and click center horizontally or center vertically option.
To change chain style, select any view in the chain and click chain button.
The attribute that controls chain style is layout_constraintHorizontal_chainStyle for horizontal chains and layout_constraintVertical_chainStyle for vertical chains. The attribute is added to only one view of the chain and that view is called head of the chain. Different chain styles you can create are spread, spread inside, packed, and weighted.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button42"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintRight_toLeftOf="@+id/button43"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="30dp"></Button>
<Button
android:id="@+id/button43"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteY="45dp"
app:layout_constraintRight_toLeftOf="@+id/button44"
app:layout_constraintLeft_toRightOf="@+id/button42"></Button>
<Button
android:id="@+id/button44"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteY="38dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@+id/button43"></Button>
</android.support.constraint.ConstraintLayout>
You can convert your existing layouts to constraint layouts. To convert an existing layout to constraint layout, open the layout, click design tab, in the component tree, right click the layout to see the convert to constraint layout option. On clicking convert to constraint layout, first it displays window where you can choose to remove nesting from the current layout and then it converts the existing layout into constraint layout.
The best feature of constrain layout editor is having the tools to create constraints automatically. There are two tools which can be used to create constraints automatically. First one is autoconnect, when it is turned on; it creates constraints to the neighboring widgets for the selected moving widget.
Second tool is called inference. It creates constrains among widgets in the layout. When it creates constraints it takes type of widgets and size of them into consideration. All you need to do to use inference is to place all views in layout editor at positions you want them to be.
While autoconnect doesn’t disturb constraints of widgets other than selected one, inference automatically creates constrains for all widgets in the layout.
Using android studio layout editor, you can create constraint layout easily and fast. You can attach constraints, add guideline, modify margins, and adjust bias, change widget dimensions, and create chains. Screen shot of the layout editor and explanation of main elements in the layout editor below.
Below is an example to show how to create registration or login screen using constraint layout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login OR Register"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"></TextView>
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="User Name"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBaseline_toBaselineOf="@+id/editText2"></TextView>
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="8"
android:inputType="textPersonName"
android:text=""
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/textView3"
app:layout_constraintLeft_toRightOf="@+id/textView4"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"></EditText>
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBaseline_toBaselineOf="@+id/editText3"></TextView>
<EditText
android:id="@+id/editText3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="8"
android:inputType="textPassword"
android:text=""
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/editText2"
app:layout_constraintLeft_toRightOf="@+id/textView5"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"></EditText>
<Button
android:id="@+id/button10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Login OR Register"
android:layout_marginTop="31dp"
app:layout_constraintTop_toBottomOf="@+id/editText3"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"></Button>
</android.support.constraint.ConstraintLayout>