ConstraintLayout — wat is het, constraints en platte hiërarchie

Auteur: IT Sectr Gepubliceerd: 2026-02-24 Leestijd: 10 min

We leggen uit wat ConstraintLayout is — een flexibel positioneringssysteem voor Android waarmee u platte hiërarchieën van views kunt bouwen met behulp van constraints (beperkingen) in plaats van geneste LinearLayouts en RelativeLayouts. ConstraintLayout lost het probleem van „layout nesting hell" op, vermindert de hiërarchiediepte tot één niveau en versnelt het renderen van het scherm. De bibliotheek maakt deel uit van Jetpack en is beschikbaar vanaf Android 2.3 (API 9) via de support-library. De basismechanismen worden beschreven in de officiële Android-documentatie.

Belangrijkste punten

  • Platte hiërarchie — ConstraintLayout maakt interfaces van elke complexiteit mogelijk zonder geneste containers, waardoor onMeasure en onLayout 2–3 keer sneller worden.
  • Constraints — positionering van elementen door randen te koppelen (layout_constraintLeft_toRightOf, layout_constraintTop_toBottomOf) aan de ouder of andere views.
  • Chain en Guideline — kettingen verdelen elementen gelijkmatig of op gewicht; richtlijnen (Guideline) geven proportionele tussenruimten in procenten.
  • Barrier en Group — een barrière past zich dynamisch aan de grootte van een groep elementen aan; Group beheert de zichtbaarheid van meerdere views tegelijk.
  • MotionLayout — een subklasse van ConstraintLayout voor het animeren van overgangen tussen constraint-toestanden met KeyFrame-ondersteuning.

Wat is ConstraintLayout?

ConstraintLayout — is een ViewGroup uit de AndroidX ConstraintLayout-bibliotheek, ontworpen voor het maken van flexibele en performante interfaces via declaratieve beperkingen (constraints). In tegenstelling tot LinearLayout, dat elementen in één lijn plaatst, of RelativeLayout, dat positioneert ten opzichte van buren, kunt u met ConstraintLayout elk element tegelijkertijd ten opzichte van andere elementen en de ouder vastzetten.

De bibliotheek werd aangekondigd op Google I/O 2016 als een oplossing om het renderen van complexe schermen te versnellen. Het belangrijkste probleem dat ConstraintLayout oplost, is het nesten van layouts. Elke geneste ViewGroup voegt ten minste twee measure-passes en één layout-pass toe. Een scherm met 4 niveaus van nesting voert 8 measure-passes uit; ConstraintLayout met dezelfde functionaliteit — slechts 2 passes. Volgens Google (Android Performance Blog, 2017) vermindert het vervangen van drie geneste LinearLayouts door één ConstraintLayout de onMeasure-tijd met 40%.

De huidige versie ConstraintLayout 2.1.4 werkt stabiel op Android 2.3+ (API 9) via AndroidX. In versie 2.0 zijn circulaire positionering, Flow (automatisch overloop van elementen) en MotionLayout-ondersteuning toegevoegd. ConstraintLayout is essentieel voor het begrijpen van moderne Android-ontwikkeling — het wordt gebruikt in Jetpack Compose als basisconcept van modifiers, in de standaardsjablonen van Android Studio en in Material Design 3.

Hoe platte hiërarchie werkt

Platte hiërarchie ConstraintLayout betekent dat alle onderliggende Views zich op hetzelfde nestniveau bevinden. In plaats van element A in een LinearLayout en de LinearLayout in een RelativeLayout te plaatsen, worden alle elementen rechtstreeks aan de ouder-ConstraintLayout of aan elkaar gekoppeld via attributen. Dit levert: lager geheugengebruik (elke ViewGroup is een object in de Java heap), versnelling van de layout-pass (minder recursieve aanroepen), voorspelbaarder gedrag bij wijzigingen van de schermgrootte.

Constraintsysteem: koppelingen, bias en marges

Constraint — is een verbinding tussen de rand van een View (of het midden ervan) en de rand van een andere View of de ouder. Elke View kan tot 8 constraints hebben: links, boven, rechts, onder, start, end, baseline en midden. Voor positionering zijn minimaal twee loodrechte constraints voldoende (bijvoorbeeld boven + links).

Attribuutformaat: app:layout_constraint[Bron]_to[Doel]Of="[id]" — waarbij Bron de gekoppelde rand is (Left, Right, Top, Bottom, Start, End, Baseline), Doel de rand van het doel. Voorbeeld: app:layout_constraintTop_toBottomOf="@+id/header" betekent „de bovenrand van het huidige element is gekoppeld aan de onderrand van het element header". Voor koppeling aan de ouder wordt de id parent gebruikt.

Bias (verschuiving) — parameter die werkt bij tegenovergestelde constraints (left + right of top + bottom). Waarde van 0 tot 1: 0 — tegen de linker/bovenrand gedrukt, 0.5 — gecentreerd, 1 — tegen de rechter/onderrand. Attributen: layout_constraintHorizontal_bias (0.0–1.0) en layout_constraintVertical_bias. Marge wordt ingesteld met standaard android:layout_margin*, maar constraint en marge werken onafhankelijk: marge is de afstand van de constraint, niet van de naburige View.

Procentuele positionering

Vanaf ConstraintLayout 1.1+ is ondersteuning voor procentuele afmetingen beschikbaar via layout_constraintWidth_percent en layout_constraintHeight_percent. Waarde 0.3 betekent 30% van de breedte/hoogte van de ouder. In combinatie met bias maakt dit het mogelijk om adaptieve layouts te maken zonder programmeren.

Chains en Guidelines: kettingen en richtlijnen

Chain (ketting) — is een groep van twee of meer Views verbonden door bidirectionele constraints (A gekoppeld aan B, B aan A). Kettingen verdelen automatisch de ruimte tussen elementen in een van de modi: spread (gelijkmatig, rekening houdend met marges), spread_inside (gelijkmatig, buitenste elementen zonder ruimte van de randen), packed (elementen tegen elkaar gedrukt met gemeenschappelijke bias). De modus wordt ingesteld met het attribuut app:layout_constraintHorizontal_chainStyle of layout_constraintVertical_chainStyle.

Guideline (richtlijn) — een hulp-View, onzichtbaar tijdens runtime, maar die een lijn voor koppeling vastlegt. Guideline kan horizontaal of verticaal zijn, gepositioneerd in dp, procenten (app:layout_constraintGuide_percent) of met afstand van de rand (app:layout_constraintGuide_begin/end). Guidelines zijn onmisbaar voor adaptieve layouts — bijvoorbeeld voor het verdelen van het scherm in twee gelijke helften ongeacht de grootte van het apparaat.

Volgens Google I/O 2017 zijn kettingen met spread_inside 15–20% efficiënter dan geneste LinearLayouts met weight, omdat ze de dubbele measure-pass vermijden die nodig is voor het berekenen van weight.

Barrier, Group en virtuele helpers

Barrier (barrière) — een virtuele View die dynamisch zijn positie aanpast aan de grootte van een groep elementen. In tegenstelling tot Guideline met een vaste positie, wordt Barrier „geduwd" door het breedste element van de groep. Als u bijvoorbeeld een titel en beschrijving met onbekende lengte heeft, kunt u met Barrier, gekoppeld aan de rechterrand van de breedste tekst, direct een pictogram ernaast plaatsen. Attributen: app:barrierDirection (left, right, top, bottom, start, end) en app:constraint_referenced_ids (komma-gescheiden lijst van id's).

Group — een virtuele container die de zichtbaarheid van meerdere Views tegelijk beheert. In plaats van setVisibility voor elk element afzonderlijk aan te roepen, volstaat het om de zichtbaarheid van één Group te wijzigen. Group heeft geen invloed op positionering — alleen op zichtbaarheid. Flow — een virtuele helper voor het maken van „vloeiende" layouts: elementen worden automatisch naar een nieuwe rij/kolom verplaatst bij ruimtegebrek, zoals tekst in een alinea. Flow ondersteunt wrapMode: none, chain en aligned.

Deze hulpmiddelen (Barrier, Group, Flow, Guideline) worden virtuele helpers genoemd omdat het geen Views in klassieke zin zijn — ze nemen geen plaats in de hiërarchie in en nemen niet deel aan focus of aanraakgebeurtenissen. Hun doel is om het onderhoud van complexe layouts te vereenvoudigen zonder geneste containers toe te voegen.

Voorbeelden: XML en Kotlin

Voorbeeld 1: Basisformulier met constraints

Een eenvoudig inlogformulier met een e-mailveld, wachtwoord en knop. Alle elementen zijn aan parent gekoppeld, behalve de knop — deze bevindt zich onder het wachtwoordveld. Er wordt platte hiërarchie gebruikt — alle drie elementen op hetzelfde niveau.

xml
<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">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/email_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="32dp"
        android:layout_marginHorizontal="16dp" />

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/password_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/email_input"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="16dp"
        android:layout_marginHorizontal="16dp" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/password_input"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="24dp"
        android:layout_marginHorizontal="16dp"
        android:text="Inloggen" />

</androidx.constraintlayout.widget.ConstraintLayout>

Alle elementen hebben een breedte van 0dp (match_constraint), ze strekken zich dus uit van start tot end, rekening houdend met horizontale marge. Dit is een alternatief voor match_parent met tussenruimten, maar zonder nesting.

Voorbeeld 2: Ketting met spread_inside

Drie knoppen, gelijkmatig horizontaal verdeeld met tussenruimten van de randen. De spread_inside-ketting plaatst de buitenste knoppen aan de randen en de middelste knop gecentreerd ertussen.

xml
<Button
    android:id="@+id/btn_left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btn_center"
    android:text="Links" />

<Button
    android:id="@+id/btn_center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn_left"
    app:layout_constraintRight_toLeftOf="@+id/btn_right"
    android:text="Midden" />

<Button
    android:id="@+id/btn_right"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toRightOf="@+id/btn_center"
    app:layout_constraintRight_toRightOf="parent"
    android:text="Rechts" />

De ketting wordt automatisch aangemaakt wanneer elementen bidirectionele constraints hebben. De spread_inside-modus wordt op elk element van de ketting ingesteld via app:layout_constraintHorizontal_chainStyle="spread_inside". Dit elimineert de noodzaak om LinearLayout met weightSum en layout_weight te gebruiken.

Voorbeeld 3: Guideline voor symmetrische layout

Twee gelijke kolommen maken via een verticale Guideline op 50%. Het linker element is gekoppeld aan de linkerrand van parent en met de rechterrand aan de guideline; het rechter element — met de linkerrand aan de guideline en aan de rechterrand van parent.

xml
<androidx.constraintlayout.widget.Guideline
    android:id="@+id/gl_midpoint"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5" />

<TextView
    android:id="@+id/left_card"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/gl_midpoint"
    android:layout_margin="8dp"
    android:background="@color/card_background" />

<TextView
    android:id="@+id/right_card"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toRightOf="@+id/gl_midpoint"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_margin="8dp"
    android:background="@color/card_background" />

Guideline met percentage 0.5 past zich automatisch aan de schermbreedte aan. Op tablet en telefoon blijven de kolomverhoudingen 50/50. Gebruik voor links/rechts nomenclatuur de start/end-attributen voor RTL-compatibiliteit.

Vergelijking: ConstraintLayout vs LinearLayout vs RelativeLayout

Vergelijkingstabel van de drie belangrijkste ViewGroups voor Android-ontwikkeling: ConstraintLayout, LinearLayout en RelativeLayout. Criteria: flexibiliteit, prestaties, codecomplexiteit en toepassingsgebieden.

KenmerkConstraintLayoutLinearLayoutRelativeLayout
NestingPlat (één niveau)Vereist nesting voor complexe layoutsEén niveau, maar beperkte flexibiliteit
Measure-prestaties2 passes (~40% sneller)4+ passes bij weight2 passes
Procentuele afmetingenJa (guide_percent, width_percent)Alleen via weight/frameNee
RTL-ondersteuningIngebouwd (start/end)IngebouwdVia start/end (API 17+)
Barrier/Group/FlowJa (virtuele helpers)NeeNee
MotionLayout-animatiesJaNeeNee
Wanneer gebruikenAlle complexe layouts, schermen met >5 elementenEenvoudige eenrichtingslijsten, rijen met knoppenEenvoudige relatieve layouts (uit legacy-code)

Volgens Android Vitals (Google, 2025) vertonen apps die ConstraintLayout als primaire container gebruiken gemiddeld 18% minder jank-frames bij het renderen van complexe schermen in vergelijking met apps op geneste LinearLayouts. Bij IT Sectr zijn we in 2018 overgestapt op ConstraintLayout als standaard voor alle XML-layouts — dit verminderde de gemiddelde hiërarchiediepte van schermen van 4.2 naar 1.8 niveau en versnelde de ontwikkeling van nieuwe formulieren met 25%.

Veelgestelde vragen

Wat is het verschil tussen match_parent en 0dp (match_constraint) in ConstraintLayout?

match_parent werkt in ConstraintLayout zoals gebruikelijk — het rekt de View uit tot de grootte van de ouder. 0dp (match_constraint) betekent dat de grootte van de View wordt berekend uit de constraints: als linker- en rechterconstraints met marge zijn ingesteld, is de breedte = parent — marginLeft — marginRight. Verschil in gedrag: match_parent negeert bias en kan buiten de grenzen treden tijdens animatie; match_constraint houdt correct rekening met alle beperkingen en wordt door Google aanbevolen als de primaire modus voor ConstraintLayout.

Hoe maak ik een adaptieve layout voor tablets met ConstraintLayout?

Gebruik een combinatie van: procentuele afmetingen (layout_constraintWidth_percent) voor elementen die een deel van het scherm moeten innemen; Guideline met percentages voor het verdelen van het scherm in zones; Barrier voor positionering ten opzichte van dynamische inhoud; Flow met wrapMode voor het verplaatsen van kaarten naar een nieuwe rij. Een alternatieve benadering — gebruik SlidingPaneLayout in combinatie met ConstraintLayout voor master-detail-interfaces op tablets.

Kan ConstraintLayout worden gebruikt in Jetpack Compose?

Jetpack Compose gebruikt ConstraintLayout niet als ViewGroup, maar biedt de Compose-versie van ConstraintLayout (androidx.constraintlayout:constraintlayout-compose) met dezelfde API in Kotlin DSL: createRefFor(), constrainAs(), linkTo(), chain(), guideFrom(). Dit is nuttig voor complexe layouts die eenvoudiger te beschrijven zijn via constraints dan via Column/Row. In Compose wordt echter aanbevolen om te beginnen met Column/Row/Box en pas over te stappen naar ConstraintLayout wanneer complexe relatieve positioneringen nodig zijn.

Hoe debug ik overlapping van elementen in ConstraintLayout?

Open in Android Studio Layout Inspector (Tools → Layout Inspector), selecteer de actieve app en beweeg over het problematische element. U ziet alle constraints, marges, padding en bias in een driedimensionale weergave. Gebruik voor XML het Design-paneel in de layout-editor — het markeert constraint-conflicten in geel en ontbrekende constraints in rood. Controleer in code of elke View twee loodrechte constraints heeft, anders komt het element op (0,0) terecht.

Samenvatting

  • ConstraintLayout — ViewGroup voor platte hiërarchie van Android-layouts via declaratieve constraints, die de nestdiepte reduceert tot 1 niveau.
  • Constraintsysteem — koppeling van randen aan parent of andere Views, bias voor verschuiving, procentuele afmetingen voor aanpassingsvermogen.
  • Chains — kettingen met spread / spread_inside / packed modi voor het verdelen van elementen zonder geneste containers.
  • Guideline en Barrier — richtlijnen (vast en procentueel) en dynamische barrières voor flexibele positionering.
  • Virtuele helpers — Group (zichtbaarheidsbeheer), Flow (automatische overloop), MotionLayout (animatie).
  • Prestaties — 40% sneller dan geneste LinearLayouts, 18% minder jank-frames.
  • Keuze — ConstraintLayout voor complexe schermen, LinearLayout voor eenvoudige rijen, RelativeLayout alleen in legacy-code.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook