Constraint Layout is a ViewGroup (i.e. a view that holds other views) which allows you to create large and complex layouts with a flat view hierarchy, and also allows you to position and size widgets in a very flexible way. It was created to help reduce the nesting of views and also improve the performance of layout files.
ConstraintLayout is very similar to RelativeLayout in such a way because, views are laid out according to relationships between sibling views and the parent layout yet it’s a lot more flexible and works better with the Layout Editor of the Android Studio’s. It was released at Google I/O 2016. Since it came into existence (i.e. as at Android studio 2.3), it has become a wildly used viewgroup and supports Android 2.3 or higher.
Table Of Contents
1. One great advantage of the constraintlayout is that you can perform animations on your ConstraintLayout views with very little code.
2. You can build your complete layout with simple drag-and-drop on the Android Studio design editor.
3. You can control what happens to a group of widgets through a single line of code.
4. Constraint Layout improve performance over other layout
It is not bundled as part of Android SDK and is available as a support library. Due to this, any update in the future would be compatible with all versions of Android.
To use Constraint Layout make sure you have declared below repository in build.gradle file
repositories { maven { url 'https://maven.google.com' } }
Now to use ConstraintLayout features in our android project, we will need to add the library to our build.gradle app module dependencies section.
Open your build.gradle (Module app) and add the code below:
dependencies { compile 'com.android.support.constraint:constraint-layout:1.1.0-beta3' }
In Android Studio design and blueprint mode are added which display the layout design in design and blueprint mode. You can enable any mode or both together according to your requirement.
Important Note: To help you understand ConstraintLayout, we will enable both(design and blueprint mode) for this tutorial.
Lets suppose you drag a TextView element in ConstraintLayout visual editor of Android Studio. Immediately after dragging you will notice a error with a message, “This view is not constrained…” So this simply means the view we created is not Constrained and we need to fix it. If we don’t fix it, the view won’t render properly when it will run in App.
Now I hover around the button, you can see different points which can be called as handles or anchor points in Constraint Layout.
Click on the any handle and drag it to make connection with something else around it.
Important Note: You will need to make at least two connection of handles with something else to make it Constrained. So this way you can create Constrained.
Resize handle – To resize the view size, you can use resize handle found at the corners which keeps constraint intact. Just simply drag and resize it according to your App UI requirements.
Side handle – The side handle are circular handle used to set the top, left, bottom and right constraints of the view.
On the right side you will notice a attribute window which share lots of details about the views that we used for View in ConstraintLayout.
You control sizing of the element by clicking on 4 side arrows to change wrap_content to match_constrained, fixed size etc.
Bias decides view placement between its constraints on an axis. By default it is set 50% and can be changed easily by dragging.
Important Note: Biasing is difficult to achieve in Linear Layout, Relative layout etc.
To delete the constrained connection, simply click on handle point and thats it.
Different Tools In ConstraintLayout:
You can also use tools like Autoconnect to let Android Studio make automatic connection of view, clear all constraints to delete all constraints in one go and infer constraint to automatic figure our the constraints for all the views on screen.
Relative Positioning is the most important type of Constraint Layout and considered as the basic block building in it. The different constraint option it offers works in relation/relative to position of one another. Those relative positioning works only in vertical and horizontal axis only.
Using horizontal axis, you can set positioning of one widget in right, left, end and start sides of other widget. While using vertical axis you can set bottom, top sides and text baseline.
Let’s now understand the concept by taking an example. In the below example, we will create two TextView. In first TextView we will write Hello and in second we will write AbhiAndroid. We will set position of “AbhiAndroid” left of the “Hello” but in the right side. Below is the XML code:
Here constraint means that the system will try to share the same location with both sides. The textview1 is left side of textview2 to be constrained to the right side of textview1.
<?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" tools:context=".MainActivity"> <TextView android:id="@+id/textview1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello "/> <TextView android:id="@+id/textview2" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@id/textview1" android:text="AbhiAndroid"/> </android.support.constraint.ConstraintLayout>
Important Note: To define a view’s position in ConstraintLayout, you must add at least one horizontal and one vertical constraint to the view. Each constraint defines the view’s position along either the vertical or horizontal axis; so each view must have a minimum of one constraint for each axis, but often more are necessary. There are several types of restrictions. In particular, the following are some of the restrictions that can be used to set a position relative to another item:
layout_constraintLeft_toLeftOf : the left border of the element is positioned relative to the left border of another element
layout_constraintLeft_toRightOf : the left border of the element is positioned relative to the right border of another element
layout_constraintRight_toLeftOf: the right border of the element is positioned relative to the left border of another element
layout_constraintRight_toRightOf: the right border of the element is positioned relative to the right border of another element.
Chains allow us to control the space between elements and chains all the selected elements to another.
To create a chain, select the elements that you want to form part of the chain, and then right click – “Chain” – “Create Horizontal or Vertical Chain”.
The different available chain style are spread, spread_inside and packed.
You can do both Horizontal or Vertical Chain at the same time.
The XML for creating a chain is different in that all the views have the constraints defined on them and the first item in the chain specifies the chainStyle.
Below is the example XML code of using chains in 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" tools:context=".MainActivity" tools:layout_editor_absoluteY="81dp"> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/button6" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button5" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
You can use guidelines to define any vertical or horizontal guideline while designing your App Layout. This will help you make Constrained connection of view to guideline and design layout keeping guideline in mind.
Important Note: On changing the margin or percentage of guideline, it will also change automatically for all connected views also.
The percent value of the constraint Width_default, allow us to set a widget to take some percentage of the available space.
<!-- the widget will take 80% of the available space --> app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.8"
The Barriers usually avoid one or more widgets/elements to bypass it. When a widget tries to pass through it, the Barrier will move itself, and avoiding the widget to be placed above it.
Below is the example XML code of using Barriers in ConstraintLayout
<?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" tools:context=".MainActivity" tools:layout_editor_absoluteY="81dp"> <Button android:id="@+id/button13" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Button" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Barriers avoid overlapping of elements" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button13" /> <android.support.constraint.Barrier android:id="@+id/barrier8" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="right" app:constraint_referenced_ids="button13,textView8" tools:layout_editor_absoluteY="511dp" /> <Button android:id="@+id/button14" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="Button" app:layout_constraintStart_toEndOf="@+id/barrier8" tools:layout_editor_absoluteY="34dp" /> </android.support.constraint.ConstraintLayout>
Group in android helps to carry out some actions on a set of widgets with the most common case being to control the visibility of a collection of widgets.
When faced with this scenario, the most common solution was to maintain yourself a list or set of views inside the Activity or Fragment, or even adding a ViewGroup and put all the views inside of it, then control the visibility of the container. Now to carry out the action on the views, you only need to add their ids as the referenced ids in the group, and group in the ConstraintLayout will propagate the actions to all plugged views.
In the below XML example code of using Groups in ConstraintLayout, we have set visibility to invisible of two Button:
<?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" tools:context=".MainActivity" tools:layout_editor_absoluteY="81dp"> <Button android:id="@+id/button15" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" tools:layout_editor_absoluteX="44dp" tools:layout_editor_absoluteY="28dp" /> <Button android:id="@+id/button16" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" tools:layout_editor_absoluteX="89dp" tools:layout_editor_absoluteY="118dp" /> <android.support.constraint.Group android:id="@+id/group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" app:constraint_referenced_ids="button16,button15" /> </android.support.constraint.ConstraintLayout>
Below we design the simple Login screen in Constraint Layout. We used ImageView, EditText, Button and TextView for designing the below layout.
Step 1: Create a new project ConstraintLayout and activity Main Activity. Here we will create a 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:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#80C938"> </android.support.constraint.ConstraintLayout>
Step 2: Add other views(imageview, edittext, button and textview) by adding both horizontal and vertical constraints to them:
<ImageView android:layout_width="146dp" android:layout_height="100dp" android:src="@drawable/abhi_android" android:id="@+id/imageView" android:layout_marginTop="96dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPersonName" android:ems="10" android:id="@+id/editText" android:layout_marginStart="16dp" android:padding="12dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:hint="Email" android:background="#ffffff" android:layout_marginTop="232dp" app:layout_constraintTop_toTopOf="parent" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPassword" android:ems="10" android:id="@+id/editText2" android:padding="12dp" android:background="#ffffff" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:hint="Password" android:layout_marginTop="304dp" app:layout_constraintTop_toTopOf="parent" /> <Button android:text="SIGN IN" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00773F" android:id="@+id/button1" android:layout_marginStart="16dp" android:paddingLeft="30dp" android:paddingRight="30dp" android:textColor="#ffffff" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginTop="408dp" app:layout_constraintTop_toTopOf="parent" /> <TextView android:text="Don't have an account?" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" android:textColor="#aaffffff" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginTop="480dp" app:layout_constraintTop_toTopOf="parent" />
Step 3: The complete xml code of simple Constraint Layout example:
<?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:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#80C938"> <ImageView android:layout_width="146dp" android:layout_height="100dp" android:src="@drawable/abhi_android" android:id="@+id/imageView" android:layout_marginTop="96dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPersonName" android:ems="10" android:id="@+id/editText" android:layout_marginStart="16dp" android:padding="12dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:hint="Email" android:background="#ffffff" android:layout_marginTop="232dp" app:layout_constraintTop_toTopOf="parent" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType="textPassword" android:ems="10" android:id="@+id/editText2" android:padding="12dp" android:background="#ffffff" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:hint="Password" android:layout_marginTop="304dp" app:layout_constraintTop_toTopOf="parent" /> <Button android:text="SIGN IN" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00773F" android:id="@+id/button1" android:layout_marginStart="16dp" android:paddingLeft="30dp" android:paddingRight="30dp" android:textColor="#ffffff" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginTop="408dp" app:layout_constraintTop_toTopOf="parent" /> <TextView android:text="Don't have an account?" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView" android:layout_marginEnd="16dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginRight="16dp" android:layout_marginStart="16dp" android:textColor="#aaffffff" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginTop="480dp" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
Output:
Now look at the layout in design mode to see the Layout of simple Login screen created using Constraint Layout.
To use ConstraintLayout,
i. Your Android Studio version must be 2.3 or higher.
ii. You must first include the ConstraintLayout’s support library.
iii. You must have at least one vertical and one horizontal constraints.
In conclusion, ConstraintLayout is a faster, better and much more efficient choice to designing large and aesthetic layouts in your Android UI.
Premium Project Source Code: