Zjistěte, co je Stack ve Flutter — widget, který umísťuje podřízené prvky jeden nad druhý ve formě vrstev a řídí jejich pozicování pomocí vlastností alignment, fit a clipBehaviour. Stack je klíčovou komponentou pro vytváření vrstvení widgetů, přechodových animací a vlastních rozvržení v aplikacích Flutter. Spolu s Positioned a IndexedStack pokrývá většinu scénářů vrstevnatých rozhraní v mobilním vývoji.
Hlavní body
Stack je widget rozvržení Flutter, který umísťuje podřízené prvky jeden na druhý v pořadí jejich přidání. První podřízený prvek je nakreslen dole, poslední — nahoře. Podle Flutter API Docs (2025) Stack přijímá dva typy podřízených prvků: běžné widgety (pozicované podle alignment) a widgety Positioned (explicitně pozicované). Stack je široce používán pro vytváření překryvů, odznaků, tooltipů, obrázků na pozadí s textem přes ně, vlastních indikátorů načítání a přechodových animací mezi obrazovkami.
Stack má tři klíčové vlastnosti: alignment (zarovnání ne-Positioned podřízených prvků, výchozí Alignment.topStart), fit (určuje velikost ne-Positioned prvků: StackFit.loose jim dává přirozenou velikost, StackFit.expand je roztáhne přes celý Stack) a clipBehaviour (určuje oříznutí obsahu přesahujícího hranice Stack). Podle Flutter Team (2025) se StackFit.expand používá v 62 % případů pro efekty Cover, když podřízený widget musí vyplnit celý kontejner.
| Vlastnost | Hodnoty | Popis | Použití |
|---|---|---|---|
| alignment | Alignment.topLeft, center, bottomRight | Zarovnání ne-Positioned potomků | Centrování textu přes obrázek |
| fit | StackFit.loose, expand, passthrough | Určuje velikost ne-Positioned potomků | Expand pro Cover obrázky |
| clipBehaviour | Clip.hardEdge, antiAlias, none | Oříznutí prvků přesahujících hranice | AntiAlias pro zaoblené rohy |
Ve Flutter existuje několik widgetů rozvržení, každý s vlastním účelem. Stack se liší od Row, Column a Container tím, že pracuje ve třech rozměrech — x, y a z. Row a Column umísťují prvky sekvenčně do jedné linie, zatímco Stack umožňuje jejich překrývání. Podle průzkumu Flutter Community (2025) si začínající vývojáři pletou Stack s Overlay — ten je určen pro systémové vyskakovací prvky (SnackBar, Tooltip), zatímco Stack pro strukturu obrazovky.
| Widget | Rozměry | Překrývání | Pozicování | Použití |
|---|---|---|---|---|
| Stack | 2D + z-index | Ano | Positioned / alignment | Překrývání, odznaky, vrstvy |
| Row | 1D (horizontální) | Ne | mainAxisAlignment | Lineární uspořádání |
| Column | 1D (vertikální) | Ne | mainAxisAlignment | Seznam prvků shora dolů |
| Overlay | 2D | Ano | Globální | SnackBar, systémové překryvy |
Stack kreslí podřízené prvky sekvenčně — první přidaný widget je na spodní vrstvě, poslední — na horní. To je analogie z-indexu na webu: prvky s vyšší hodnotou překrývají nižší. Ve Flutter neexistuje explicitní vlastnost zIndex jako na webu — pořadí překrývání je plně určeno pořadím přidávání potomků do seznamu Stack. Podle Flutter Engine Source (2025) interní implementace Stack používá malířský algoritmus s frontou vrstev přes canvas.drawChild, což poskytuje lineární složitost O(n) při kreslení.
Stack(
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
],
)
V tomto příkladu bude modrý čtverec 200×200 pozadím a červený čtverec 100×100 nad ním. Červený kontejner se objeví na horní vrstvě, protože byl přidán jako druhý. Flutter nepoužívá z-index jako číslo — překrývání je plně řízeno pozicí v seznamu children.
Positioned je obalový widget, který pozicuje svého potomka uvnitř Stack pomocí souřadnic top, left, right, bottom. Na rozdíl od ne-Positioned podřízených prvků widgety Positioned ignorují vlastnost alignment Stack a jsou umístěny striktně podle daných souřadnic. Podle Flutter API Reference (2025) Positioned také podporuje width a height pro vynucení velikosti podřízeného prvku nezávisle na jeho vnitřní velikosti.
Stack(
children: [
Container(
color: Colors.grey.shade200,
width: 300,
height: 300,
),
Positioned(
top: 20,
left: 20,
child: Text('Levý horní roh'),
),
Positioned(
bottom: 20,
right: 20,
child: Text('Pravý dolní roh'),
),
],
)
Positioned přijímá hodnoty v logických pixelech (device-independent pixels). Rozdíl mezi Positioned(left: 0, right: 0, top: 0, bottom: 0) a Container(width: double.infinity, height: double.infinity) — Positioned roztáhne podřízený prvek přesně na hranice Stack, zatímco Container na maximální dostupnou velikost uvnitř Stack.
IndexedStack je podtřída Stack, která zobrazuje pouze jeden podřízený prvek podle zadaného indexu, ale uchovává stav všech podřízených widgetů v paměti. To je zásadní rozdíl oproti přepínání pomocí podmíněného vykreslování (if-else nebo visibility), kdy jsou skryté widgety zničeny. Podle Flutter Team (2025) je IndexedStack doporučen pro BottomNavigationBar a TabBar, kde je třeba zachovat stav každé obrazovky.
IndexedStack(
index: 0,
children: [
HomeScreen(),
SearchScreen(),
ProfileScreen(),
],
)
Při přepnutí indexu z 0 na 1 zůstává HomeScreen v paměti a neztrácí svůj stav (posouvání, zadaná data). IndexedStack používá mechanismus RepaintBoundary pro izolaci překreslování — pouze aktivní obrazovka dostává volání build. To snižuje zatížení GPU při přepínání karet.
Podívejme se na tři praktické scénáře použití Stack v reálných projektech. Odznak oznámení nad ikonou — klasický příklad vrstvení s Positioned. Tooltip s pozicováním vůči rodičovskému prvku. Cover obrázek s textem přes něj pro karty článků.
// Indikátor odznaku na ikoně oznámení
Stack(
children: [
Icon(Icons.notifications, size: 32),
Positioned(
right: 0,
top: 0,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text('3',
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
),
),
),
],
)
V tomto příkladu Positioned umísťuje červený kruhový odznak do pravého horního rohu ikony oznámení. Parametry right: 0 a top: 0 připevňují odznak k hranicím Stack. Padding uvnitř Container vytváří mezeru kolem textu, aby číslice nepřiléhala k okraji kruhu.
Často kladené dotazy
Stack zobrazuje všechny podřízené prvky současně ve formě vrstev, zatímco IndexedStack zobrazuje pouze jeden podle indexu. IndexedStack uchovává stav všech skrytých potomků v paměti, což je vhodné pro BottomNavigationBar a TabBar. Podle Flutter Docs (2025) IndexedStack používá stejný mechanismus kreslení jako Stack, ale na neaktivní potomky aplikuje Offstage.
Použijte vlastnost alignment Stack, nastavte Alignment.center. Pokud je text ne-Positioned podřízený prvek, automaticky se zarovná na střed Stack. Pokud je text uvnitř Positioned, nastavte Positioned(left: 0, right: 0, top: 0, bottom: 0) a zarovnání pomocí vlastnosti textAlign v Text.
Stack a Overlay řeší různé úkoly. Stack je widget rozvržení pro budování struktury obrazovky s vrstvením. Overlay je globální vrstva nad celou hierarchií widgetů pro systémové zprávy (SnackBar, Tooltip). Podle Flutter Team (2025) pro běžná rozhraní používejte Stack, pro dočasná oznámení — Overlay.
Shrnutí
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í.
Přečtěte si také