Expanded to widget Flutter, który sprawia, że element potomny wypełnia całą dostępną przestrzeń w kontenerze Flex. Gdy Row lub Column rozdzielają miejsce między dziećmi, Expanded zajmuje wolną przestrzeń po uwzględnieniu elementów nieelastycznych. Według oficjalnej dokumentacji Flutter (2026), Expanded to jeden z najczęściej używanych widgetów layoutowych — stosowany jest w procentowym układzie interfejsów, budowaniu kart, list i paneli. Jego główną zaletą jest automatyczne obliczanie szerokości lub wysokości na podstawie współczynnika flex bez jawnego określania rozmiarów.
Najważniejsze
Expanded to widget-opakowanie, który przyjmuje child i zmusza go do rozszerzenia, aby wypełnić dostępną przestrzeń w kontenerze Flex (Row, Column, Flex). Expanded nie ma własnej reprezentacji wizualnej — zarządza tylko constraints przekazywanymi do elementu potomnego.
U podstaw Expanded leży mechanizm Flex dostarczany przez framework Flutter. Gdy Row lub Column obliczają rozmiary swoich dzieci, najpierw przydzielają miejsce elementom nieelastycznym (zwykłym widgetom o stałych rozmiarach), a pozostałą przestrzeń rozdzielają między Expanded i Flexible dziećmi proporcjonalnie do ich flex-factorów.
Expanded używa Flexible.fit = FlexFit.tight. Oznacza to, że dziecko Expanded musi zająć całą przydzieloną mu przestrzeń, nawet jeśli jego własny rozmiar jest mniejszy. W przeciwieństwie do Flexible z Fit.loose, gdzie dziecko może być mniejsze niż przydzielony obszar, Expanded wymusza rozciągnięcie zawartości.
Podsumowanie: Expanded to podstawowe narzędzie do tworzenia proporcjonalnych układów we Flutter. Używaj go, gdy chcesz, aby element gwarantowanie zajął całą dostępną szerokość lub wysokość.
Expanded i Flexible — oba rozdzielają przestrzeń w kontenerach Flex, ale zachowują się zasadniczo inaczej. Różnica polega na właściwości fit, która określa, czy dziecko może być mniejsze niż dostępne miejsce.
Expanded ma sztywny model zachowania: jego fit równa się FlexFit.tight. Oznacza to, że widget potomny otrzymuje constraints równe dostępnej przestrzeni — ani więcej, ani mniej. Jeśli dziecko jest mniejsze, jest rozciągane. Jeśli większe — jest ściskane. Flexible używa FlexFit.loose, pozwalając elementowi potomnemu być dowolnego rozmiaru w obrębie przydzielonej przestrzeni.
W praktyce: jeśli wewnątrz Row znajdują się dwa Expanded z flex=1, każdy zajmie dokładnie połowę szerokości. Jeśli zastąpisz je Flexible z fit.loose, każde dziecko może być mniejsze niż połowa, jeśli jego własny rozmiar jest mniejszy — pozostałe miejsce pozostanie puste.
Podsumowanie: używaj Expanded do ścisłych proporcjonalnych układów, Flexible — gdy dziecko może być mniejsze niż dostępne miejsce. Jeśli nie jesteś pewien — zaczynaj od Expanded, daje bardziej przewidywalne zachowanie.
Flex-factor (parametr flex) — wartość liczbowa określająca część dostępnej przestrzeni, którą otrzyma Expanded. Domyślnie flex=1, co oznacza równomierne rozdzielenie między wszystkie Expanded dzieci.
Algorytm dystrybucji działa w trzech krokach. Pierwszy: Flutter oblicza intrinsic size wszystkich nieelastycznych dzieci. Drugi: pozostała przestrzeń jest dzielona przez sumę wszystkich flex-factorów. Trzeci: każdy Expanded otrzymuje część równą swojemu flex-factorowi pomnożonemu przez rozmiar jednej jednostki flex.
Na przykład Row o szerokości 300px zawiera dwa Expanded: pierwszy z flex=2, drugi z flex=1. Wolna przestrzeń (300px minus nieelastyczne dzieci) jest dzielona na 3 części. Pierwszy otrzymuje 2/3, drugi — 1/3. Jeśli nie ma nieelastycznych dzieci, pierwszy otrzyma 200px, drugi — 100px.
Flex-factor może być dowolną dodatnią liczbą całkowitą. Wartość 0 to szczególny przypadek: Expanded z flex=0 zachowuje się jak zwykły nieelastyczny widget, zajmując minimalną przestrzeń według rozmiaru dziecka. To zachowanie jest równoważne brakowi Expanded.
Podsumowanie: flex-factor to klucz do budowania elastycznych układów. Używaj proporcji 1:1 dla równych kolumn, 2:1 dla paneli z obszarem głównym i bocznym, 3:1 dla interfejsów z wąską nawigacją.
Przykład 1 demonstruje podstawowe użycie Expanded w Row do tworzenia trzech równych kolumn.
Row(
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.green,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
)
W tym przykładzie trzy Expanded z flex=1 (domyślnie) dzielą szerokość Row równomiernie. Kontenery rozciągają się na całą wysokość ustawioną przez Row i zajmują równe części. Takie podejście jest wygodne do tworzenia układów kolumnowych z proporcjonalnym rozdzieleniem.
Przykład 2 pokazuje użycie różnych flex-factorów do tworzenia układu z panelem bocznym i główną treścią.
Row(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.grey.200,
child: const Center(
child: Text('Panel boczny'),
),
),
),
Expanded(
flex: 3,
child: Container(
color: Colors.white,
child: const Center(
child: Text('Obszar treści'),
),
),
),
],
)
Drugi przykład tworzy typowy layout z panelem bocznym (25%) i obszarem głównym (75%). flex=1 i flex=3 dają proporcję 1:3. Przy zmianie szerokości ekranu proporcje są zachowywane automatycznie — to podstawa adaptacyjnych interfejsów.
Podsumowanie: Expanded z różnymi flex-factorami to standardowe narzędzie do budowania adaptacyjnych układów. Połączenie Expanded w Column pozwala tworzyć zarówno poziome, jak i pionowe proporcjonalne rozmieszczenia.
Błąd 1: użycie Expanded poza Row, Column lub Flex. Jeśli umieścisz Expanded bezpośrednio w Stack, ListView lub innym kontenerze niebędącym Flex, Flutter wyrzuca LayoutException z komunikatem „Expanded widgets must be placed inside Flex widgets”. Rozwiązanie: sprawdzaj widget rodzica — tylko Row, Column lub Flex.
Błąd 2: umieszczenie Expanded wewnątrz ListView bez określenia shrinkWrap. ListView domyślnie ma nieskończoną wysokość w kierunku przewijania i Expanded nie może obliczyć swojego udziału. Rozwiązanie: użyj shrinkWrap: true lub owiń ListView w SizedBox o stałej wysokości.
Błąd 3: wiele Expanded z sumarycznym flex przekraczającym dostępną przestrzeń. Jeśli wewnątrz Row o ograniczonej szerokości znajdują się Expanded oraz widgety o dużym intrinsic size, może wystąpić overflow. Rozwiązanie: sprawdzaj minimalne rozmiary nieelastycznych dzieci i w razie potrzeby używaj FittedBox lub Flex fit.
Błąd 4: zagnieżdżone Expanded w Column wewnątrz Row. Jeśli Expanded wewnątrz Column zawiera inny Expanded wewnątrz Row, może wystąpić konflikt constraints. Rozwiązanie: ograniczaj głębokość zagnieżdżenia lub używaj ConstrainedBox do jawnego określania rozmiarów na pośrednich poziomach.
Podsumowanie: Expanded wymaga prawidłowego kontekstu rodzica. Zawsze sprawdzaj, czy Expanded znajduje się bezpośrednio w Row, Column lub Flex, i unikaj zagnieżdżenia bez jawnych rozmiarów.
Często zadawane pytania
SizedBox.expand wymusza rozciągnięcie dziecka do rozmiarów określonych przez zewnętrzne constraints, ale nie uczestniczy w dystrybucji flex. Expanded działa tylko wewnątrz kontenerów Flex i uwzględnia flex-factor przy rozdzielaniu wolnej przestrzeni między dziećmi.
Nie. Stack nie jest kontenerem Flex, a użycie Expanded wewnątrz niego spowoduje LayoutException. Do rozciągania dzieci w Stack używaj Positioned.fill lub BoxConstraints.expand.
Domyślnie flex=1. Wszystkie Expanded bez jawnego flex otrzymają równe części wolnej przestrzeni. Jeśli w Row są trzy Expanded bez flex, każdy zajmie dokładnie jedną trzecią dostępnego miejsca.
Umieść Expanded w Row do rozciągania w poziomie. Do rozciągania w pionie użyj Expanded wewnątrz Column. Jeśli potrzebujesz ograniczyć rozmiary, owiń Expanded lub jego dziecko w SizedBox.
Expanded działa z Flex, w tym Row i Column jako jego podklasy. Wrap nie jest kontenerem Flex i nie obsługuje Expanded. Do rozdzielania przestrzeni w Wrap używaj innych metod, na przykład RunAlignment.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również