LinearLayout: základy, orientace a rozložení váhy v Androidu

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

Vysvětlujeme základy LinearLayout — základní ViewGroup v Android SDK pro zarovnání podřízených prvků do jedné řady: svisle (LinearLayout.VERTICAL) nebo vodorovně (LinearLayout.HORIZONTAL). LinearLayout zůstává nejjednodušším a nejrychlejším způsobem, jak vytvořit řadu tlačítek, seznam nastavení nebo vstupní formulář, když složitost rozvržení nepřesahuje 5–10 prvků. Atributy layout_weight a orientation řídí rozložení prostoru a směr. Podrobná specifikace — v LinearLayout API Reference.

Hlavní body

  • Orientace — LinearLayout umísťuje prvky sekvenčně svisle (VERTICAL) nebo vodorovně (HORIZONTAL), nastavená pomocí android:orientation.
  • layout_weight — rozdělení volného prostoru úměrně váze prvků; součet vah určuje podíl každého.
  • gravity vs layout_gravity — android:gravity zarovnává obsah uvnitř LinearLayout; android:layout_gravity zarovnává samotný prvek uvnitř rodiče.
  • Vnořování — hlavní nevýhoda: pro složitou mřížku je zapotřebí vnořit několik LinearLayout, což snižuje výkon.
  • Baseline alignment — zarovnání textových prvků podle základní linie písma nezávisle na padding a výšce prvku.

Co je LinearLayout?

LinearLayout — jedna z prvních ViewGroup v Android SDK (API Level 1), určená pro sekvenční umísťování podřízených prvků do jedné řady nebo sloupce. Každý nový prvek je umístěn po předchozím a směr je nastaven atributem android:orientation. LinearLayout je nejjednodušší a nejpředvídatelnější Android kontejner, což z něj činí ideální volbu pro lineární rozhraní: řady tlačítek, seznamy nastavení s ikonou a textem, horizontální menu.

Historicky je LinearLayout první ViewGroup, se kterou se seznámí začínající Android vývojář. Jeho výhodou je transparentnost: podřízené prvky jsou umístěny striktně v pořadí deklarace, bez skrytých pravidel pro pozicování. Na rozdíl od RelativeLayout, kde může být prvek připojen k libovolnému sousedovi, nebo ConstraintLayout s jeho systémem omezení, LinearLayout funguje na principu 'první vlevo/nahoře, druhý po něm, třetí po druhém'. Podle Google I/O 2017 používá 78% obrazovek v top 1000 aplikacích Google Play LinearLayout jako hlavní nebo pomocný kontejner.

Hlavní metrika LinearLayout — LinearLayout.MeasureSpec — systém správy velikosti. Při orientaci VERTICAL je šířka každého prvku rovna šířce rodiče (match_parent nebo pevná) a výška je určena obsahem nebo atributem. Pro HORIZONTAL obráceně: výška je rovna rodičovské, šířka — podle obsahu. Pokud v HORIZONTAL řadě celková šířka prvků překročí šířku rodiče, prvky mohou vyčnívat z obrazovky (pokud se nepoužije weight).

Vnitřní struktura

LinearLayout přepisuje onMeasure a onLayout z ViewGroup. Při orientaci VERTICAL umísťuje onLayout prvky na ose Y: první child — y=0, druhý — y=prev.bottom + divider.hidden, a tak dále. Při HORIZONTAL — na ose X. Divider (oddělovač) se nastavuje pomocí android:divider a android:showDividers (beginning, middle, end). Oddělovač může být barva, drawable nebo vlastní Shape zdroj.

Orientace a Gravity: VERTICAL a HORIZONTAL

Orientace — klíčový atribut LinearLayout, který určuje směr umísťování podřízených prvků. android:orientation="vertical" řadí prvky shora dolů; android:orientation="horizontal" — zleva doprava (nebo zprava doleva při RTL lokalizaci). Pokud orientace není nastavena, standardně se používá HORIZONTAL (ve starších verzích) — ale explicitní uvedení je povinné pro předvídatelné chování.

android:gravity — zarovnání obsahu uvnitř LinearLayout. Přijímá kombinace: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Hodnota gravity="center" pro VERTICAL rozvržení umístí všechny prvky na střed horizontálně. android:layout_gravity — atribut podřízeného prvku, který jej zarovnává uvnitř rodičovského LinearLayout. Příklad: tlačítko s layout_gravity="right" ve VERTICAL rozvržení bude přitisknuto k pravému okraji.

Rozdíl: gravity — vlastnost rodiče (jak jsou děti umístěny uvnitř), layout_gravity — vlastnost dítěte (jak se chová uvnitř rodiče). Chyba záměny těchto atributů je jednou z nejčastějších u začátečníků.

Baseline alignment

Pro HORIZONTAL rozvržení s textovými prvky (TextView, Button, EditText) je užitečné android:baselineAligned="true" — zarovnává všechny texty podle základní linie písma, nezávisle na jejich padding, size nebo height. Díky tomu vypadá řada s ikonou, nadpisem a popisem vizuálně úhledně: text neskáče nahoru a dolů.

layout_weight: rozložení váhy

layout_weight — atribut podřízeného prvku LinearLayout, který určuje, jakou část volného prostoru zabere. Funguje pouze ve směru orientace (šířka pro HORIZONTAL, výška pro VERTICAL). Vzorec výpočtu: velikost = vlastní velikost + (volný prostor × (váha prvku / součet všech vah)). Volný prostor = velikost rodiče — součet všech vlastních velikostí dětí.

layout_weight je efektivnější než pevné velikosti pro adaptivní rozhraní. Například, pokud levý panel má zabírat 30% obrazovky a pravý — 70%, nastavte weight=3 a weight=7. Pro správnou funkci se obvykle nastavuje velikost ve směru na 0dp (android:layout_width="0dp" pro HORIZONTAL), pak je vlastní velikost prvku považována za nulovou a celá velikost je určena pouze weight. Toto je standardní doporučení Google (Android Developers Guide, 2024).

Důležité: váhy se sčítají pro všechny prvky v LinearLayout, včetně těch bez weight (jejich váha je považována za 0). Pokud má jeden prvek weight=1 a druhý weight=2, první zabere 1/3 volného prostoru, druhý — 2/3. weightSum (atribut rodiče) umožňuje nastavit maximální součet vah — pokud jsou váhy dětí v součtu menší než weightSum, rozdíl zůstává jako prázdný prostor.

Příklady kódu: XML rozvržení

Příklad 1: Svislý formulář s weight

Přihlašovací formulář se skládá ze tří prvků: pole email (zabírá 2/4), pole hesla (1/4) a tlačítko (1/4) výšky obrazovky. Všechny tři prvky s weight fungují pouze v orientaci VERTICAL po výšce.

xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:hint="Email" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:hint="Heslo"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="Přihlásit se" />

</LinearLayout>

Výška každého prvku = (parent_height — padding) × (weight / sumWeights). email získá 2/4 výšky, heslo a tlačítko — každý 1/4. Všechna height=0dp, takže vlastní velikost se nebere v úvahu — funguje pouze weight.

Příklad 2: Vodorovný panel nástrojů

Panel se třemi tlačítky: ikona zpět (wrap_content), nadpis (vyplní zbytek) a ikona menu (wrap_content). weight pro nadpis = 1, tlačítka bez weight.

xml
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    android:gravity="center_vertical">

    <ImageButton
        android:id="@+id/btn_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_arrow_back" />

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Nadpis"
        android:textSize="18sp" />

    <ImageButton
        android:id="@+id/btn_menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_more_vert" />

</LinearLayout>

Tlačítka zpět a menu zabírají přesně tolik, kolik je potřeba pro ikonu. Nadpis (TextView) s width=0dp a weight=1 se roztáhne na veškerý zbývající prostor mezi nimi. gravity="center_vertical" zarovnává všechny prvky na svislý střed.

Příklad 3: Vnořené LinearLayout pro složitou kartu

Karta produktu: vodorovná řada (obrázek + svislý blok textu). Vnější LinearLayout HORIZONTAL, vnitřní — VERTICAL pro nadpis, popis a cenu.

xml
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/product_image"
        android:scaleType="centerCrop" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginStart="12dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Název produktu"
            android:textStyle="bold"
            android:textSize="16sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stručný popis produktu ve dvou řádcích"
            android:textSize="14sp"
            android:textColor="@color/gray" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1 299 rub."
            android:textSize="18sp"
            android:textColor="@color/accent" />

    </LinearLayout>

</LinearLayout>

Obrázek vlevo (80×80dp), vpravo — svislý blok tří řádků textu. Vnitřní LinearLayout má weight=1, takže zabírá veškerý zbývající prostor po obrázku. Toto je klasický vzor karty seznamu, který se vyskytuje v tisících aplikací.

Problém vnořování a alternativy

Hlavní nevýhoda LinearLayout — potřeba vnořených kontejnerů pro složitá rozvržení. Pokud je třeba umístit prvky do mřížky 2×2 nebo vytvořit řadu se zarovnáním na dva okraje, jsou zapotřebí nejméně 2–3 úrovně vnoření. Každá úroveň LinearLayout přidává 2 průchody onMeasure, což na slabých zařízeních vede k znatelným zasekáváním při vykreslování.

Podle Android Performance Blog (Google, 2017) každá další úroveň vnoření zvyšuje čas rozvržení o 30–50 μs. Pro seznam 20 prvků se 3 úrovněmi vnoření může zpoždění dosáhnout 3 ms na prvek — to je znatelný jank při rolování. ConstraintLayout řeší tento problém pomocí ploché hierarchie, nahrazuje 3–4 vnořené LinearLayout jedním kontejnerem s omezeními.

Doporučení: používejte LinearLayout pro jednoduchá lineární rozvržení (do 10 prvků, jedna úroveň vnoření). Pro karty seznamů, formuláře s různým zarovnáním a obrazovky s tabulkovou strukturou zvolte ConstraintLayout. Pro opakující se prvky v RecyclerView používejte ConstraintLayout v souboru rozvržení prvku — to je zásadní pro výkon rolování.

Často kladené otázky

Proč layout_weight nefunguje?

Nejčastější příčina — není nastavena velikost ve směru na 0dp. Pro rozvržení HORIZONTAL je potřeba android:layout_width="0dp", pro VERTICAL — android:layout_height="0dp". Pokud má prvek wrap_content nebo match_parent, weight nemusí fungovat nebo může dát neočekávaný výsledek. Druhá příčina — weightSum na rodiči je menší než součet weight dětí. Třetí — použití match_parent na podřízeném prvku v opačném směru.

Jaký je rozdíl mezi layout_weight a weightSum?

layout_weight se nastavuje na každém podřízeném prvku a určuje jeho podíl na volném prostoru. weightSum — atribut rodiče LinearLayout, který nastavuje maximální součet vah. Standardně weightSum = součtu všech layout_weight dětí. Pokud nastavíte weightSum = 3 a děti s weight=1, každý zabere 1/3. Pokud jsou jen dvě děti s weight=1, zbývající 1/3 bude prázdná. weightSum je vhodný pro fixaci proporcí bez přepočítávání při přidávání/odebírání prvků.

Jak odstranit mezery mezi prvky LinearLayout?

Standardně nejsou žádné mezery — prvky jsou umístěny těsně vedle sebe. Pokud se mezery objevily, zkontrolujte: android:divider a android:showDividers na rodiči, android:layout_margin na podřízených prvcích. Dodatečně může ovlivnit android:weightSum — pokud prvky používají weight, může mezi nimi zůstat prázdný prostor kvůli nesprávnému výpočtu. Pro nulové mezery nastavte všem dětem margin=0dp a odstraňte divider.

Co je rychlejší: LinearLayout nebo ConstraintLayout?

Pro jednoduchá jednosměrná rozvržení (1–5 prvků v řadě/sloupci) LinearLayout je o něco rychlejší — neplýtvá prostředky na výpočet omezení. Pro složitá rozvržení (více než 5 prvků, mřížky, různé typy zarovnání) ConstraintLayout je rychlejší, protože používá plochou hierarchii místo vnořených LinearLayout. Podle testů Google (Android Performance Blog) vítězí ConstraintLayout na rozvrženích vyžadujících 3+ úrovně vnoření LinearLayout.

Shrnutí

  • LinearLayout — základní Android ViewGroup pro sekvenční umísťování prvků svisle nebo vodorovně.
  • Orientace — android:orientation="vertical" (sloupec) nebo "horizontal" (řada) určuje směr rozvržení.
  • layout_weight — mechanismus rozdělení volného prostoru úměrně váze prvků s velikostmi 0dp.
  • Gravity — android:gravity (zarovnání dětí uvnitř rodiče) vs android:layout_gravity (zarovnání dítěte v rodiči).
  • Vnořování — hlavní nevýhoda: pro složitá rozvržení jsou potřeba 2–3 úrovně, což zpomaluje vykreslování o 30–50 μs na úroveň.
  • Výběr — LinearLayout pro jednoduché řady/sloupce (do 10 prvků), ConstraintLayout pro složitá rozvržení.
  • Přizpůsobivost — kombinace weight + 0dp + baseline alignment pokrývá 80% úloh lineárního rozvržení.

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é