Flexible — widget Flutter, který řídí, jak podřízený prvek zabírá dostupný prostor v Flex-kontejneru. Na rozdíl od Expanded, Flexible nenutí dítě vyplnit celou přidělenou oblast — podřízený widget může být menší a zbývající místo zůstává prázdné. Podle oficiální dokumentace Flutter (2026) je Flexible nezbytný ve scénářích, kde je vyžadováno flexibilní rozdělení prostoru bez vynuceného natahování: tlačítka s minimální šířkou, textové bloky s přirozenou velikostí a prvky s intrinsic constraints.
Hlavní body
Flexible — obalový widget, který poskytuje podřízenému prvku flexibilní prostor v Flex-kontejneru. Flexible, stejně jako Expanded, se účastní rozdělování volného prostoru, ale s klíčovým rozdílem: dítě Flexible může zabírat méně místa, než mu bylo přiděleno, pokud je jeho vlastní velikost menší než dostupný prostor.
Flexible používá Flex-algoritmus Flutter k výpočtu dostupného prostoru. Nejprve framework dotáže všechna neflexibilní děti (widgety bez Flexible/Expanded) a vypočítá jejich intrinsic size. Zbývající prostor je rozdělen mezi flexibilní děti proporcionálně podle jejich flex-faktoru. Po přidělení prostoru Flexible zkontroluje fit — pokud je loose, na podřízený prvek se aplikuje omezení “ne více než přiděleno”, což mu umožňuje zůstat malý.
Vlastnost Flexible: pokud má podřízený widget vlastní minimální rozměry (například Text s dlouhým řetězcem), Flexible přidělí požadovaný prostor, nenatahuje ho násilně. To činí Flexible nenahraditelným pro prvky, jejichž velikost by měla být určena obsahem, nikoli kontejnerem.
Závěr: používejte Flexible, když potřebujete rezervovat prostor pro prvek, ale nechcete ho nutit k natahování. To zachovává přirozené velikosti obsahu při flexibilním rozdělení layoutu.
FlexFit — výčet dvou hodnot: tight a loose. Od výběru fit závisí, zda bude podřízený widget vynuceně natažen na velikost přiděleného prostoru.
FlexFit.tight: podřízený prvek obdrží tight constraints — minimální a maximální velikost jsou rovny přidělenému prostoru. Dítě musí zabírat přesně tolik místa, kolik přidělil Flex-algoritmus. Pokud je dítě menší — je nataženo. Pokud je větší — je stlačeno. Chování identické s Expanded.
FlexFit.loose: podřízený prvek obdrží loose constraints — minimální velikost je 0, maximální je rovna přidělenému prostoru. Dítě může mít libovolnou velikost od 0 do maximum. Pokud je dítě malé (například Text s krátkým řetězcem), zaujme svou přirozenou šířku a zbytek prostoru zůstává prázdný.
Závěr: FlexFit.loose — volba pro textové bloky a prvky s přirozenou velikostí. FlexFit.tight — pro přísné sloupcové rozvržení, kde všechny prvky musí mít stejnou šířku nebo výšku.
Flexible a Expanded vypadají podobně, ale řeší různé úkoly. Expanded vždy natáhne dítě na plný dostupný prostor. Flexible může ponechat prázdný prostor kolem dítěte, pokud je velikost obsahu menší než přidělený podíl.
Scénář pro Flexible: uvnitř Row jsou dvě tlačítka. První — „Koupit“ (krátký text), druhé — „Přidat do košíku“ (dlouhý text). S Expanded se obě tlačítka natáhnou na stejnou šířku a krátký text bude mít obrovské okraje. S Flexible každé tlačítko zaujme šířku svého textu a volný prostor zůstane mezi nimi nebo na okrajích.
Scénář pro Expanded: uvnitř Column jsou tři karty, které by měly mít stejnou výšku bez ohledu na obsah. Expanded rovnoměrně rozdělí dostupnou výšku a každá karta se natáhne na stejnou velikost. Flexible s loose zde není vhodný — malá karta zůstane malá, čímž naruší jednotný design.
Závěr: vyberte Flexible, když obsah určuje velikost prvku a prázdný prostor kolem něj je přijatelný. Vyberte Expanded, když všechny prvky musí mít stejnou velikost bez ohledu na obsah.
Příklad 1 demonstruje základní použití Flexible s FlexFit.loose v Row.
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.amber,
child: const Text('krátký'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.cyan,
child: const Text('dlouhý text pro demo'),
),
),
],
)
V příkladu oba Flexible s loose fit. První kontejner s krátkým textem zaujímá svou přirozenou šířku. Druhý s dlouhým textem — svou. Row přiděluje každému polovinu dostupné šířky, ale loose fit umožňuje kontejnerům být menší a volný prostor zůstává mezi nimi prázdný.
Příklad 2 — srovnání Flexible s Tight a Loose fit v Column.
Column(
children: [
Flexible(
fit: FlexFit.tight,
child: const Card(
child: ListTile(
title: Text('Tight — nataženo na plnou výšku'),
),
),
),
const SizedBox(
height: 8,
),
Flexible(
fit: FlexFit.loose,
child: const Card(
child: ListTile(
title: Text('Loose — přirozená výška'),
),
),
),
],
)
V Column první Flexible (tight) natáhne Card na polovinu dostupné výšky. Druhý Flexible (loose) — Card zaujímá výšku podle obsahu a zbytek prostoru zůstává prázdný. Vizuálně je vidět, jak tight vynuceně vyplňuje oblast, zatímco loose zachovává kompaktní velikost.
Závěr: v produkčním kódu se Flexible s loose aplikuje pro pole formulářů, tlačítka a textové bloky. Flexible s tight — ekvivalent Expanded, používá se pro rovnoměrné rozdělení.
Chyba 1: použití Flexible mimo Flex-kontejner. Stejně jako Expanded, Flexible vyhazuje LayoutException, pokud není uvnitř Row, Column nebo Flex. Řešení: vždy kontrolujte rodičovský řetězec widgetů.
Chyba 2: záměna Flexible a Expanded. Vývojáři často používají Expanded, když je potřeba Flexible s loose fit, a naopak. Výsledek: Expanded natáhne prvek s krátkým textem a vytvoří velká prázdná pole. Řešení: pokud velikost prvku může být menší než přidělený prostor — použijte Flexible(fit: FlexFit.loose).
Chyba 3: nulový flex-faktor. Flexible s flex=0 se chová jako neflexibilní widget, což nemusí být zřejmé. Vývojář očekává flexibilní chování, ale prvek zaujímá minimální velikost. Řešení: flex by měl být ≥1 pro aktivní rozdělování prostoru.
Chyba 4: Flexible uvnitř ScrollView bez omezení velikosti. Pokud je Flexible v Column uvnitř SingleChildScrollView, scroll-kontejner poskytuje nekonečný prostor a flex-rozdělení nefunguje. Řešení: omezte velikost scroll-kontejneru pomocí SizedBox nebo ConstrainedBox.
Závěr: Flexible vyžaduje stejnou pozornost vůči rodičovskému kontextu jako Expanded. Rozdíl je pouze ve fit — vybírejte ho vědomě podle úkolu.
Často kladené dotazy
Expanded — je Flexible s pevným fit=tight. Rozdíl je v tom, že Expanded má pevné připojení k vyplnění celého dostupného prostoru, zatímco Flexible může použít loose fit k zachování přirozené velikosti dítěte.
Pro tlačítka s různou délkou textu použijte Flexible(fit: FlexFit.loose). Každé tlačítko zaujme šířku podle obsahu a mezi nimi nebude disproporce. Expanded udělá všechna tlačítka stejně široká.
Nastavte fit: FlexFit.tight — Flexible bude nutit dítě vyplnit celý přidělený prostor. V tomto režimu je Flexible zcela identický s Expanded v chování.
Ano, pokud je dítě větší než přidělený prostor. Flexible předává constraints s maximální velikostí rovnou podílu Flex-kontejneru. Pokud dítě tuto velikost překračuje, je stlačeno v rámci constraints.
Ano, Flexible funguje s jakýmkoli Flex-kontejnerem, včetně Row, Column a základního widgetu Flex s libovolným direction. Flex umožňuje nastavení nestandardních směrů prostřednictvím mainAxisAlignment a crossAxisAlignment.
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é