Constraint Layout Quick Guide

Hitesh Sahu
5 min readMay 21, 2019

Why Constraint Layout?

TLDR: Nested layout have double taxation on UI performance. Each nested layout object adds cost to the layout stage.The flatter your hierarchy, the less time that it takes for the layout stage to complete.

Double Taxation: Having to perform more than one layout-and-measure iteration is referred to as double taxation.

Double Taxation causes

  • Relative Layout make first pass to position child views and second pass to finalize final their position
  • A Horizontal LinearLayout View.
  • A Vertical LinearLayout with add measureWithLargestChild in which case the framework may need to do a second pass to resolve the proper sizes of objects.
  • GridLayout with its container using relative positioning, weights, gravity or RelativeLayout.

How Constraintlayout Helps reduce

Constraint Layout allows to create layouts with a flat view hierarchy (no nested view groups). It work similar to RelativeLayout but have flat hierarchy hence no double taxation.

  • Constraint layout is similar to Auto Layout of iOS where we can set constraints on all view.
  • Each view must have at least one Horizontal and one Vertical constraint for position. If there is not it will render at (0,0) top-left on screen.
  • If you there's missing constraints then Layout Editor show error in Component Tree.

Constraint handles

  1. Resize : Squares on Corner of view. Used to change size of view by dragging corners
  2. Anchor: Circles on sides of view. Used to set absolute or relative position. Empty circle mean no constrain, filler circle mean constrained is defined.
  3. BaseLine: Sausage shaped control inside view. Used to base align siblings. Right click on view to select show Baseline control.
  4. Sizing: Size of View:
    - Fixed Size . | — — — |
    - Match Parent — /\/\/\ —
    - Wrap Content <<<--
  5. Bias: Value from 0.0 to 1.0, used to set horizontal or vertical relative position of view wrt its parent. Bias 1.0 mean to end of parent, .5 mean center of parent, 0,.0 mean to start of parent.To set center in parent:
 app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintVertical_bias="0.5"

Constraint layout vs Relativelayout

Relative layout alignment attributes:

  • layout_toTopOf put view on Top of another.
  • layout_toBottomOf put view on Bottom of another.
  • layout_toLeftOf put view on Left of another.
  • layout_toRightOf put view on Right of another.

ConstraintLayout attributes:

TOP

  • layout_constraintTop_toTopOf — Align the top of the desired view to the top of another.
  • layout_constraintTop_toBottomOf — Align the top of the desired view to the bottom of another.

BOTTOM

  • layout_constraintBottom_toTopOf — Align the bottom of the desired view to the top of another.
  • layout_constraintBottom_toBottomOf — Align the bottom of the desired view to the bottom of another.

LEFT

  • layout_constraintLeft_toTopOf — Align the left of the desired view to the top of another.
  • layout_constraintLeft_toBottomOf — Align the left of the desired view to the bottom of another.
  • layout_constraintLeft_toLeftOf — Align the left of the desired view to the left of another.
  • layout_constraintLeft_toRightOf — Align the left of the desired view to the right of another.

RIGHT

  • layout_constraintRight_toTopOf — Align the right of the desired view to the top of another.
  • layout_constraintRight_toBottomOf — Align the right of the desired view to the bottom of another.
  • layout_constraintRight_toLeftOf — Align the right of the desired view to the left of another.
  • layout_constraintRight_toRightOf — Align the right of the desired view to the right of another.

Positioning relative to the parent

Positioning relative to the Sibling

Constraint Layout as Linear Layout using Chains

  • Select childs to Chain-> Right click → Chains-> Horizontal/Vertical Chain.
  • Right Click Again ->Align -> Center Vertical/ Center In Parent
  • For Weight first select the View in the editor, and then set height or width 0dp and set weight

android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

  • Right Click On View in Chain -> Cycle Chain Mode,

Cycle chain mode is like adjust spacing between chain items . There are three possible modes:

  1. spread: Arrange all view at equal distance
  2. spread_inside: First and last view on extreme left and right side while center views spread equal distance.
  3. packed: closed together

Constraint Layout as Percent Layout

Add Guidelines. Guidelines are Utility class representing a Guideline helper object for ConstraintLayout.

Helper objects are not displayed on device (they are marked as View.GONE) and are only used for layout purposes. They only work within a ConstraintLayout.

A Guideline can be either horizontal or vertical:

  • Vertical Guidelines have a width of zero and the height of their ConstraintLayout parent
  • Horizontal Guidelines have a height of zero and the width of their ConstraintLayout parent

Positioning a Guideline is possible in three different ways:

  • layout_constraintGuide_begin: specifying a fixed distance from the left or the top of a layout
  • layout_constraintGuide_end: specifying a fixed distance from the right or the bottom of a layout
  • layout_constraintGuide_percent : specifying a percentage of the width or the height of a layout

Creating Guidelines

Guidelines are present in common-> Layouts of Visual editor on left side

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

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

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>

Example of all mentioned scenarios:

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
android:background="@color/cardview_shadow_start_color"
android:fillViewport="true">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!--A Centerd View-->

<TextView
android:id="@+id/basicTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text=" Constrain Layout Example"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />

<!--Constrain Layout as Horizontal Linear Layout-->

<TextView
android:id="@+id/titleHorizontalLL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="Horizontal Linear Layout"
android:textSize="30sp"
app:layout_constraintHorizontal_bias="0.452"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/backgroundImage"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />

<Button
android:id="@+id/button17"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Child 1"
app:layout_constraintEnd_toStartOf="@+id/button16"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleHorizontalLL"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />

<Button
android:id="@+id/button16"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Child 2"
app:layout_constraintBottom_toBottomOf="@+id/button17"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@+id/button17"
app:layout_constraintTop_toTopOf="@+id/button17"
app:layout_constraintVertical_bias="1.0"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />

<!--Constrain Layout as Frame Layout-->

<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="@drawable/lake"
app:layout_goneMarginRight="@dimen/activity_vertical_margin"
app:layout_constraintStart_toStartOf="heding"
app:layout_constraintEnd_toEndOf="@+id/info"
app:layout_constraintTop_toTopOf="@+id/heding"
app:layout_constraintBottom_toBottomOf="@+id/info"
/>

<!--Constrain Layout as Relative Layout-->

<TextView
android:id="@+id/heding"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Lake Tahoe "
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toEndOf="@+id/backgroundImage"
app:layout_constraintTop_toTopOf="@+id/backgroundImage"
tools:layout_constraintBottom_creator="1"
android:textColor="#FFF"
tools:layout_constraintTop_creator="1" />

<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="LakeTahoe is a large freshwater lake in Sierra Naveda"
android:textSize="15sp"
android:textColor="#FFF"
app:layout_constraintBottom_toBottomOf="@+id/backgroundImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toEndOf="@+id/backgroundImage"
app:layout_constraintTop_toBottomOf="@+id/heding"
app:layout_constraintVertical_bias="1.0"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />


<ImageView
android:id="@+id/backgroundImage"
android:layout_width="104dp"
android:layout_height="67dp"
android:layout_marginStart="16dp"
android:layout_marginTop="40dp"
android:background="@drawable/lake"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/basicTitle" />


<!--Constrain Layout as Vertical Linear Layout-->

<TextView
android:id="@+id/verticalLLHeading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vertical Linear Layout"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lakeDescription"
app:layout_constraintVertical_chainStyle="packed"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />

<Button
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="View"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/verticalLLHeading" />

<Button
android:id="@+id/share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Share"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view" />

<Button
android:id="@+id/visit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Visit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/share" />


<Button
android:id="@+id/visasasasit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Visit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/visit" />


<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@string/lake_tahoe_image"
android:onClick="toggleMode"
android:scaleType="centerCrop"
android:src="@drawable/lake"
app:layout_constraintDimensionRatio="h,16:9"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button16"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1" />

<TextView
android:id="@+id/lakeTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/lake_tahoe_title"
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />

<TextView
android:id="@+id/lakeDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:text="@string/lake_discription"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="@+id/lakeTitle"
app:layout_constraintRight_toRightOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/lakeTitle"
app:layout_constraintVertical_bias="0.0"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintTop_creator="1" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

Good Read:

--

--