Skip to content
intermediate Phase 3 · UI with XML & Views

ConstraintLayout Deep Dive

Master chains, guidelines, barriers, and groups for flat, performant layouts.

45m
3 problems
Topic Progress 0%

Chains and Guidelines

Chains

A chain connects two or more views in the same axis. The first and last views in the chain are connected to the opposite ends of the parent. Chains distribute remaining space based on their style:

<!-- Spread chain — equal spacing between items -->
<TextView
    android:id="@+id/label1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Item 1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/label2"
    app:layout_constraintHorizontal_chainStyle="spread" />

<TextView
    android:id="@+id/label2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Item 2"
    app:layout_constraintStart_toEndOf="@id/label1"
    app:layout_constraintEnd_toEndOf="parent" />

Chain styles:

Style Behavior
spread Equal gaps between items and edges
spread_inside Items pushed to edges, no gap at parent edges
packed Items centered together with no gaps

Weighted Chains

Add layout_constraintHorizontal_weight to views in a chain to distribute space proportionally (like LinearLayout weight):

<TextView
    android:id="@+id/left"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="2"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toStartOf="@id/right"
    app:layout_constraintHorizontal_chainStyle="spread" />

<TextView
    android:id="@+id/right"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintStart_toEndOf="@id/left"
    app:layout_constraintEnd_toEndOf="parent" />

This gives left twice the space of right.

Guidelines

Guidelines are invisible lines that views can constrain to. They let you define responsive margins without hardcoding:

<!-- Vertical guideline at 25% from the left -->
<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.25" />

<!-- Views constrain to the guideline -->
<TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toEndOf="@id/guideline"
    app:layout_constraintTop_toTopOf="parent" />

Guideline types:

  • app:layout_constraintGuide_percent — percentage of parent size (0.0 to 1.0)
  • app:layout_constraintGuide_begin — fixed offset from the start edge
  • app:layout_constraintGuide_end — fixed offset from the end edge

Barriers

Barriers move dynamically based on the largest view they reference. Instead of constraining to a fixed guideline, you constrain to a barrier that shifts when content grows:

<!-- Barrier moves right of the tallest view -->
<androidx.constraintlayout.widget.Barrier
    android:id="@+id/barrier"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="end"
    app:constraint_referenced_ids="name,email,phone" />

<!-- This view stays to the right of whichever is tallest -->
<TextView
    android:id="@+id/editBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Edit"
    app:layout_constraintStart_toEndOf="@id/barrier"
    app:layout_constraintTop_toTopOf="@id/name" />

Use barriers when content is dynamic (localized text, user-generated content) and you can't predict which view will be the tallest.

Responsive Layouts with Constraints

Constrained Dimensions

Instead of fixed dp widths, constrain a view's width to a percentage of the parent or a ratio to its height:

<!-- 50% of parent width -->
<TextView
    android:id="@+id/halfWidth"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintWidth_percent="0.5"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

Aspect Ratios

Force a view to maintain a specific width:height ratio:

<!-- Always 16:9 regardless of width -->
<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintDimensionRatio="16:9"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

layout_constraintDimensionRatio works when at least one dimension is 0dp (match constraints). The ratio can be specified as width:height or as a float.

Horizontal and Vertical Bias

Bias positions a view between two constraints without changing the constraint structure:

<!-- Positioned 30% from the left constraint -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.3"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintVertical_bias="0.5" />

Bias defaults to 0.5 (centered). Values closer to 0 push left/top; values closer to 1 push right/bottom. Bias only takes effect when both opposing constraints are present.

Complete Responsive Layout Example

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Top bar: 8dp from edges, anchored to top -->
    <TextView
        android:id="@+id/header"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Dashboard"
        android:textAppearance="?attr/textAppearanceHeadlineMedium"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:padding="16dp" />

    <!-- Barrier below header for dynamic content -->
    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/headerBarrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="header" />

    <!-- Card: 50% width, 16:9 ratio, starts at barrier -->
    <com.google.android.material.card.MaterialCardView
        android:id="@+id/card"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintWidth_percent="0.5"
        app:layout_constraintDimensionRatio="4:3"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/headerBarrier"
        app:layout_margin="8dp">
        <!-- Card content -->
    </com.google.android.material.card.MaterialCardView>

    <!-- Info: fills remaining space to the right of card -->
    <TextView
        android:id="@+id/info"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Details here"
        app:layout_constraintStart_toEndOf="@id/card"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/card"
        app:layout_constraintBottom_toBottomOf="@id/card"
        app:layout_constraintVertical_bias="0.5"
        android:padding="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

This layout adapts to any screen size: the card stays 50% wide, the info fills the rest, and the header is always at the top.

Quiz

1. What does a spread chain do in ConstraintLayout?

Question 1 options

2. When should you use a Barrier instead of a Guideline?

Question 2 options

3. How does layout_constraintHorizontal_bias affect a view?

Question 3 options

4. What does layout_constraintDimensionRatio require?

Question 4 options

Flashcards

Question

What are the three chain styles in ConstraintLayout?

Answer

spread (equal gaps everywhere), spread_inside (gaps between items only, no edge gaps), packed (all items centered together).

Question

What is the difference between a Guideline and a Barrier?

Answer

Guideline is a fixed position (percent or dp offset). Barrier moves dynamically based on the largest view it references.

Question

When does layout_constraintHorizontal_bias take effect?

Answer

Only when both horizontal constraints are set (e.g., start_toStartOf and end_toEndOf). Without opposing constraints, bias has nothing to interpolate.

Question

How do you set a 50% width constraint on a view?

Answer

Set layout_width to 0dp and use app:layout_constraintWidth_percent="0.5". This constrains the view to half the parent width.

Revision Notes

Key Takeaways

  • 1. Chains distribute space among connected views — spread, spread_inside, and packed are the three styles
  • 2. Barriers shift dynamically with content size, making them ideal for localized or dynamic text
  • 3. Aspect ratios require at least one 0dp dimension to compute the constrained dimension
  • 4. Bias only takes effect when both opposing constraints are present
  • 5. Guidelines provide fixed reference points; Barriers provide dynamic reference points

Interview Tips

  • Explain when you'd use a Barrier over a Guideline — dynamic content vs fixed positioning
  • Be ready to describe chain styles and when to use weighted chains vs spread
  • Know that aspect ratios need at least one 0dp dimension
  • Discuss how bias lets you create non-centered layouts without removing constraints

Cheat Sheet

ConstraintLayout Deep Dive Cheat Sheet

Chains:

  • Connect first and last views to opposite parent edges
  • Styles: spread, spread_inside, packed
  • Weight: layout_constraintHorizontal_weight for proportional sizing

Guidelines:

  • Invisible lines for consistent spacing
  • Percent: layout_constraintGuide_percent (0.0–1.0)
  • Fixed: layout_constraintGuide_begin/end (dp)

Barriers:

  • Move based on the largest referenced view
  • Use when content size is dynamic/unpredictable
  • barrierDirection: start, end, top, bottom, left, right

Responsive techniques:

  • layout_constraintWidth_percent for percentage widths
  • layout_constraintDimensionRatio for aspect ratios
  • layout_constraintHorizontal_bias for non-centered positioning
  • Bias only works with opposing constraints

Key rule:
Every view needs at least one horizontal + one vertical constraint or it jumps to 0,0.