ConstraintLayout — co to je, omezení a plochá hierarchie

Autor: IT Sectr Publikováno: 2026-02-24 Doba čtení: 10 min

Vysvětlujeme, co je ConstraintLayout — flexibilní systém pozicování pro Android, který umožňuje vytvářet ploché hierarchie zobrazení pomocí omezení (constraints) namísto vnořených LinearLayout a RelativeLayout. ConstraintLayout řeší problém "zapleteného vnořování" (layout nesting hell), snižuje hloubku hierarchie na jednu úroveň a urychluje vykreslování obrazovky. Knihovna je součástí Jetpack a je dostupná od Android 2.3 (API 9) přes support-library. Základní mechanismy jsou popsány v oficiální dokumentaci Android.

Hlavní body

  • Plochá hierarchie — ConstraintLayout umožňuje vytvářet rozhraní libovolné složitosti bez vnořených kontejnerů, což zrychluje onMeasure a onLayout 2–3krát.
  • Omezení — pozicování prvků připojením okrajů (layout_constraintLeft_toRightOf, layout_constraintTop_toBottomOf) k rodiči nebo jiným zobrazením.
  • Chain a Guideline — řetězce rozdělují prvky rovnoměrně nebo podle váhy; vodítka (Guideline) nastavují proporcionální mezery v procentech.
  • Barrier a Group — bariéra se dynamicky přizpůsobuje velikosti skupiny prvků; Group spravuje viditelnost několika zobrazení najednou.
  • MotionLayout — podtřída ConstraintLayout pro animaci přechodů mezi stavy omezení s podporou KeyFrame.

Co je ConstraintLayout?

ConstraintLayout — je ViewGroup z knihovny AndroidX ConstraintLayout, určený pro vytváření flexibilních a výkonných rozhraní prostřednictvím deklarativních omezení. Na rozdíl od LinearLayout, které řadí prvky do jedné řady, nebo RelativeLayout, které pozicuje relativně k sousedům, ConstraintLayout umožňuje připojit každý prvek relativně k libovolným jiným prvkům a rodiči současně.

Knihovna byla oznámena na Google I/O 2016 jako řešení pro urychlení vykreslování složitých obrazovek. Klíčovým problémem, který ConstraintLayout řeší, je vnořování rozvržení. Každý vnořený ViewGroup přidá nejméně dva průchody measure a jeden průchod layout. Obrazovka se 4 úrovněmi vnoření provádí 8 průchodů measure; ConstraintLayout se stejnou funkcionalitou — pouze 2 průchody. Podle údajů Google (Android Performance Blog, 2017) nahrazení tří vnořených LinearLayout jedním ConstraintLayout snižuje čas onMeasure o 40%.

Aktuální verze ConstraintLayout 2.1.4 stabilně funguje na Android 2.3+ (API 9) přes AndroidX. Ve verzi 2.0 se objevilo kruhové pozicování, Flow (automatický přesun prvků) a podpora MotionLayout. ConstraintLayout je nezbytný pro pochopení moderního vývoje Android — používá se v Jetpack Compose jako základní koncept modifikátorů, ve výchozích šablonách Android Studio a v Material Design 3.

Jak funguje plochá hierarchie

Plochá hierarchie ConstraintLayout znamená, že všechna podřízená zobrazení jsou na stejné úrovni vnoření. Místo umístění prvku A do LinearLayout a LinearLayout do RelativeLayout jsou všechny prvky připojeny přímo k nadřazenému ConstraintLayout nebo k sobě navzájem prostřednictvím atributů. To přináší: nižší spotřebu paměti (každý ViewGroup je objekt v Java heap), zrychlení průchodu layout (méně rekurzivních volání), předvídatelnější chování při změně velikosti obrazovky.

Systém omezení: připojení, bias a okraje

Omezení — je spojení mezi okrajem jednoho zobrazení (nebo jeho středem) a okrajem jiného zobrazení nebo rodiče. Každé zobrazení může mít až 8 omezení: levé, horní, pravé, dolní, start, end, baseline a střed. Pro pozicování stačí minimálně dvě kolmá omezení (např. horní + levé).

Formát atributu: app:layout_constraint[Zdroj]_to[Cíl]Of="[id]" — kde Zdroj je připojovaný okraj (Left, Right, Top, Bottom, Start, End, Baseline), Cíl je okraj cíle. Příklad: app:layout_constraintTop_toBottomOf="@+id/header" znamená "horní hranice aktuálního prvku je připojena k dolní hranici prvku header". Pro připojení k rodiči se používá id parent.

Bias (posun) — parametr fungující při protilehlých omezeních (left + right nebo top + bottom). Hodnota od 0 do 1: 0 — přitisknuto k levému/hornímu okraji, 0.5 — na středu, 1 — k pravému/dolnímu okraji. Atributy: layout_constraintHorizontal_bias (0.0–1.0) a layout_constraintVertical_bias. Okraj se nastavuje standardními android:layout_margin*, ale omezení a okraj fungují nezávisle: okraj je vzdálenost od omezení, ne od sousedního zobrazení.

Procentuální pozicování

Od ConstraintLayout 1.1+ je dostupná podpora procentuálních velikostí prostřednictvím layout_constraintWidth_percent a layout_constraintHeight_percent. Hodnota 0.3 znamená 30% šířky/výšky rodiče. V kombinaci s bias to umožňuje vytvářet adaptivní rozvržení bez programování.

Chains a Guidelines: řetězce a vodítka

Chain (řetězec) — je skupina dvou nebo více zobrazení spojených obousměrnými omezeními (A připojeno k B, B k A). Řetězce automaticky rozdělují prostor mezi prvky v jednom z režimů: spread (rovnoměrně, s ohledem na okraje), spread_inside (rovnoměrně, krajní prvky bez mezery od okrajů), packed (prvky přitisknuté k sobě se společným bias). Režim se nastavuje atributem app:layout_constraintHorizontal_chainStyle nebo layout_constraintVertical_chainStyle.

Guideline (vodítko) — pomocné zobrazení, neviditelné za běhu, ale určující čáru pro připojení. Guideline může být vodorovný nebo svislý, umístěný v dp, procentech (app:layout_constraintGuide_percent) nebo s odstupem od okraje (app:layout_constraintGuide_begin/end). Vodítka jsou nepostradatelná pro adaptivní rozvržení — například pro rozdělení obrazovky na dvě stejné poloviny bez ohledu na velikost zařízení.

Podle údajů Google I/O 2017 jsou řetězce s spread_inside o 15–20% výkonnější než vnořené LinearLayout s weight, protože se vyhýbají dvojitému průchodu measure potřebnému pro výpočet weight.

Barrier, Group a virtuální pomocníci

Barrier (bariéra) — virtuální zobrazení, které dynamicky přizpůsobuje svou pozici velikosti skupiny prvků. Na rozdíl od Guideline s pevnou pozicí je Barrier "tlačen" nejširším prvkem skupiny. Například pokud máte nadpis a popis neznámé délky, Barrier připojený k pravému okraji nejširšího textu umožňuje umístit ikonu hned za ně. Atributy: app:barrierDirection (left, right, top, bottom, start, end) a app:constraint_referenced_ids (seznam id oddělených čárkou).

Group — virtuální kontejner spravující viditelnost několika zobrazení současně. Místo volání setVisibility pro každý prvek zvlášť stačí změnit viditelnost jednoho Group. Group neovlivňuje pozicování — pouze viditelnost. Flow — virtuální pomocník pro vytváření "tekutých" rozvržení: prvky se automaticky přesouvají na nový řádek/sloupec při nedostatku místa, jako text v odstavci. Flow podporuje wrapMode: none, chain a aligned.

Tyto nástroje (Barrier, Group, Flow, Guideline) se nazývají virtuální pomocníci, protože nejsou zobrazeními v klasickém smyslu — nezabírají místo v hierarchii a neúčastní se fokusu nebo dotykových událostí. Jejich cílem je zjednodušit údržbu složitých rozvržení bez přidávání vnořených kontejnerů.

Příklady: XML a Kotlin

Příklad 1: Základní formulář s omezeními

Jednoduchý přihlašovací formulář s polem email, heslem a tlačítkem. Všechny prvky jsou připojeny k parent, kromě tlačítka — to je pod polem hesla. Používá plochou hierarchii — všechny tři prvky na stejné úrovni.

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="Přihlásit" />

</androidx.constraintlayout.widget.ConstraintLayout>

Všechny prvky mají šířku 0dp (match_constraint), tedy se táhnou od start do end omezení s ohledem na vodorovný okraj. To je obdoba match_parent s mezerami, ale bez vnoření.

Příklad 2: Řetězec s spread_inside

Tři tlačítka, rovnoměrně rozmístěná vodorovně s mezerami od okrajů. Řetězec spread_inside umísťuje krajní tlačítka k okrajům a prostřední tlačítko doprostřed mezi ně.

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="Vlevo" />

<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="Střed" />

<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="Vpravo" />

Řetězec se vytváří automaticky, když mají prvky obousměrná omezení. Režim spread_inside se nastavuje na libovolném prvku řetězce pomocí app:layout_constraintHorizontal_chainStyle="spread_inside". To eliminuje potřebu používat LinearLayout s weightSum a layout_weight.

Příklad 3: Guideline pro symetrické rozvržení

Vytvoření dvou stejných sloupců pomocí svislého Guideline na 50%. Levý prvek je připojen k levému okraji parent a pravým okrajem ke guideline; pravý prvek — levým okrajem ke guideline a k pravému okraji 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 s procentem 0.5 se automaticky přizpůsobuje šířce obrazovky. Na tabletu a telefonu zůstanou poměry sloupců 50/50. Pro levou/pravou nomenklaturu používejte atributy start/end pro kompatibilitu RTL.

Srovnání: ConstraintLayout vs LinearLayout vs RelativeLayout

Srovnávací tabulka tří hlavních ViewGroup pro vývoj Android: ConstraintLayout, LinearLayout a RelativeLayout. Kritéria: flexibilita, výkon, složitost kódu a oblasti použití.

VlastnostConstraintLayoutLinearLayoutRelativeLayout
VnořeníPloché (jedna úroveň)Vyžaduje vnoření pro složitá rozvrženíJedna úroveň, ale omezená flexibilita
Výkon measure2 průchody (~40% rychlejší)4+ průchody při weight2 průchody
Procentuální velikostiAno (guide_percent, width_percent)Pouze přes weight/frameNe
Podpora RTLVestavěná (start/end)VestavěnáPřes start/end (API 17+)
Barrier/Group/FlowAno (virtuální pomocníci)NeNe
MotionLayout animaceAnoNeNe
Kdy použítVšechna složitá rozvržení, obrazovky s >5 prvkyJednoduché jednosměrné seznamy, řady tlačítekJednoduchá relativní rozvržení (z legacy kódu)

Podle Android Vitals (Google, 2025) vykazují aplikace používající ConstraintLayout jako hlavní kontejner v průměru o 18% méně jank snímků při vykreslování složitých obrazovek ve srovnání s aplikacemi na vnořených LinearLayout. V IT Sectr jsme přešli na ConstraintLayout jako standard pro všechna XML rozvržení v roce 2018 — to snížilo průměrnou hloubku hierarchie obrazovek ze 4,2 na 1,8 úrovně a urychlilo vývoj nových formulářů o 25%.

Často kladené otázky

Jaký je rozdíl mezi match_parent a 0dp (match_constraint) v ConstraintLayout?

match_parent v ConstraintLayout funguje jako obvykle — roztahuje zobrazení na velikost rodiče. 0dp (match_constraint) znamená, že velikost zobrazení se vypočítá z omezení: pokud jsou nastavena levé a pravé omezení s okrajem, šířka = parent — marginLeft — marginRight. Rozdíl v chování: match_parent ignoruje bias a může při animaci překročit hranice; match_constraint správně zohledňuje všechna omezení a Google jej doporučuje jako hlavní režim pro ConstraintLayout.

Jak vytvořit adaptivní rozvržení pro tablety s ConstraintLayout?

Použijte kombinaci: procentuální velikosti (layout_constraintWidth_percent) pro prvky, které mají zabírat část obrazovky; Guideline s procenty pro rozdělení obrazovky na zóny; Barrier pro pozicování vůči dynamickému obsahu; Flow s wrapMode pro přesun karet na nový řádek. Alternativní přístup — použití SlidingPaneLayout v kombinaci s ConstraintLayout pro master-detail rozhraní na tabletech.

Lze použít ConstraintLayout v Jetpack Compose?

Jetpack Compose nepoužívá ConstraintLayout jako ViewGroup, ale poskytuje Compose verzi ConstraintLayout (androidx.constraintlayout:constraintlayout-compose) se stejným API v Kotlin DSL: createRefFor(), constrainAs(), linkTo(), chain(), guideFrom(). To je užitečné pro složitá rozvržení, která se snáze popisují pomocí omezení než pomocí Column/Row. V Compose se však doporučuje začínat s Column/Row/Box a přejít na ConstraintLayout pouze tehdy, když jsou potřeba složitá relativní pozicování.

Jak ladit překrývání prvků v ConstraintLayout?

V Android Studio otevřete Layout Inspector (Tools → Layout Inspector), vyberte běžící aplikaci a najeďte na problematický prvek. Uvidíte všechna omezení, okraje, padding a bias v trojrozměrném zobrazení. Pro XML použijte panel Design v editoru rozvržení — zvýrazňuje konflikty omezení žlutě a chybějící omezení červeně. V kódu zkontrolujte, že každé zobrazení má dvě kolmá omezení, jinak prvek skončí na (0,0).

Shrnutí

  • ConstraintLayout — ViewGroup pro plochou hierarchii Android rozvržení prostřednictvím deklarativních omezení, snižující hloubku vnoření na 1 úroveň.
  • Systém omezení — připojení okrajů k parent nebo jiným zobrazením, bias pro posun, procentuální velikosti pro přizpůsobivost.
  • Chains — řetězce s režimy spread / spread_inside / packed pro distribuci prvků bez vnořených kontejnerů.
  • Guideline a Barrier — vodítka (pevná a procentuální) a dynamické bariéry pro flexibilní pozicování.
  • Virtuální pomocníci — Group (správa viditelnosti), Flow (automatický přesun), MotionLayout (animace).
  • Výkon — o 40% rychlejší než vnořené LinearLayout, o 18% méně jank snímků.
  • Volba — ConstraintLayout pro složité obrazovky, LinearLayout pro jednoduché řady, RelativeLayout pouze v legacy kódu.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také