ConstraintLayout

Emre Arslan
The Startup
Published in
6 min readFeb 16, 2021

--

ConstraintLayout has already been one of the most fundamental components in Android Development with lots of effective features to create complex and robust layouts. You may consider it as a more advanced Relative Layout with lots of improvements and cool properties 😎. It can help the developer to get rid of lots of boilerplate code and improve code readability without compromising performance.

When/Why should we use it?

As I said, ConstraintLayout provides lots of cool features but everything comes with a price! ConstraintLayout is one of the most expensive layouts in Android Development. That’s why it should be chosen wisely. Unlike, LinearLayout or FrameLayout, it should not be used nested unless it’s absolutely required. (Actually, even if it’s required, it can still be divided into different parts so 🚫NEVER USE NESTED CONSTRAINT LAYOUT 🚫)

One of the main reasons why you should use constraint layout is that you can create a RESPONSIVE UI with that. What I mean by that, when it comes to device variation (in different screen sizes) Android is no doubt is the leader. Only God knows how many there are outside !!! That’s why our code should be working perfectly fine in all screen sizes.

“Write once run everywhere”.

Another reason is that it decreases view hierarchy. Developers can make complex UI’s without having too many nested views. It increases code readability and reduces the boilerplate code.

The last one is for those who don’t like coding layouts. Constraint Layout can also be used by drag&drop elements one by one in Visual Editor. Just put the element wherever you want and your code will be automatically generated. (Newbies already liked it 🤩🤩🤩).

Now let’s take a closer look at what kind of features it offers one by one.

Before you use ConstraintLayout you should add its dependency into your build.gradle file.

dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
}

Now we are ready to go.

Relative Positioning

This one is what makes ConstraintLayout that powerful. You can position elements relatively with each other (just like in RelativeLayout). Constraints could be either another view or directly the parent. Let’s see it in action.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/button_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Centered"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:text="Right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/button_center"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:text="Left"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_center"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_above"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="Above"
app:layout_constraintBottom_toTopOf="@id/button_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<Button
android:id="@+id/button_below"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Below"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_center" />

<Button
android:id="@+id/button_bottom"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

<Button
android:id="@+id/button_top"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

With the help of these constraint properties, you can align elements the way you like without having nested layouts. Also, you don’t have to worry about the screen size. It will be handled automatically according to screen size.

At first, it may seem hard to use but as you keep practicing, you will see they are really practical to use.

Warning: To give a margin in a direction, you must give the constraint to that direction. Otherwise, the margin will not work!

Gone Margin

Visibility of an item has always been one of the biggest concerns in layouts. Imagine that, you have lots of items in your layout but you just wanna show some of them according to the requirement. But you don’t know how to keep View’s position when its parent is GONE. “Gone Margin” is introduced with ConstraintLayout to solve this issue.

Imagine that you have a hierarchy as shown above. You want to make A’s visibility GONE. When A is GONE, B will automatically slide to A’s position. In order to prevent that you can give gone_margin to the related direction.

You can give gone_margin just like the normal margin from 4 different sides of the view.

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

GuideLine

Guidelines could be very useful if you know how to use them properly. They are simply invisible lines that can be created vertically and horizontally and can be used to set constraints of the views.

They can be used in many ways. For example, you may divide the screen into equal pieces or you can give start and end margins. (It reduces boilerplate margin codes. Imagine giving a fixed margin value to each and every one of the views??? Nah, just use guidelines with the desired margin values and give it as a constraint ).

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_vertical_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_vertical_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="16dp" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_horizontal1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.25" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_horizontal2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_horizontal3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.75" />

As you see, the screen is divided into four equal parts vertically and it has fixed start and endpoints horizontally.

Barrier

Barriers are another cool helper like GuideLine that comes with ConstraintLayout. Its main purpose, as its name suggests, is to create an invisible barrier at runtime to make sure no matter what(run-time width or height changes) view has not crossed the barrier. (Imagine you have a textView that must not exceed a view regardless of its size). See the gif below:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"><androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="view1,view2,view3"
/>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="250dp"
android:layout_height="250dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/barrier"
/><View
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
..../>
<View
android:id="@+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
..../><View
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
..../>
</androidx.constraintlayout.widget.ConstraintLayout>

Chain

When you use the LinearLayout “weight” property before, Chain should be familiar to you. The chain is simply used to link views vertically or horizontally.

Chains can be used differently according to your need. You can decide the position of the linked items by setting layout_constraintHorizontal_chainStyle

or

layout_constraintVertical_chainStyle

on the first element of a chain, the behavior of the chain will change according to the specified style (default is CHAIN_SPREAD).

  • CHAIN_SPREAD: evenly distributes all the views in the chain (default style).
  • CHAIN_SPREAD_INSIDE: positions the first and last element on the edge, and evenly distribute the rest of the elements.
  • CHAIN_PACKED: the elements of the chain will be packed together. The horizontal or vertical bias attribute of the child will then affect the positioning of the packed elements.

ViewGroup

ViewGroup as its name suggests groups the views. Imagine you have a layout that you must change lots of views visibility in it accordingly. One way is to put them in a layout and change the layout visibility directly. But having nested views is not exactly what we want. Besides, the views sometimes cannot be in the same layout due to their position. There might some other views between them or something else. You can add views into a group either in XML or in Design Editor by selecting all the views and clicking “Add Group”.

<android.support.constraint.Group
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids=
"button_center,
button_left,
button_right"
/>

That’s all for now. You can start using ConstraintLayout like a boss 😎.

For detailed info you can visit the official documents

https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html

https://developer.android.com/training/constraint-layout/index.html

--

--