Flexible: co to jest, zasada działania i konfiguracja w programowaniu mobilnym

Autor: IT Sectr Opublikowano: 2026-07-03 Czas czytania: 6 min

Flexible — widget Flutter, który zarządza tym, jak element podrzędny zajmuje dostępne miejsce w kontenerze Flex. W przeciwieństwie do Expanded, Flexible nie zmusza dziecka do wypełnienia całego przydzielonego obszaru — widget podrzędny może być mniejszy, a pozostałe miejsce pozostaje puste. Według oficjalnej dokumentacji Flutter (2026), Flexible jest niezbędny w scenariuszach, gdzie wymagane jest elastyczne rozmieszczenie przestrzeni bez wymuszonego rozciągania: przyciski z minimalną szerokością, bloki tekstowe z naturalnym rozmiarem i elementy z intrinsic constraints.

Najważniejsze

  • Flexible — widget layout do elastycznego rozdzielania przestrzeni w Row, Column lub Flex
  • FlexFit.loose pozwala dziecku być mniejszym niż przydzielone miejsce, FlexFit.tight — wymusza wypełnienie
  • Flexible z loose jest odpowiedni dla widgetów, których rozmiar powinien być określany przez zawartość
  • Różnica z Expanded: Expanded nie ma parametru fit i zawsze działa jako tight
  • Flex-factor działa tak samo dla Flexible i Expanded — proporcja wolnego miejsca

Co to jest Flexible

Flexible — to widget-opakowanie, zapewniający elementowi podrzędnemu elastyczne miejsce w kontenerze Flex. Flexible, podobnie jak Expanded, uczestniczy w rozdzielaniu wolnego miejsca, ale z kluczową różnicą: dziecko Flexible może zająć mniej miejsca, niż mu przydzielono, jeśli jego własny rozmiar jest mniejszy niż dostępny.

Flexible używa Flex-algorytmu Flutter do obliczania dostępnej przestrzeni. Najpierw framework odpytuje wszystkie nieelastyczne dzieci (widgety bez Flexible/Expanded) i oblicza ich intrinsic size. Pozostałe miejsce jest dzielone pomiędzy elastyczne dzieci proporcjonalnie do ich flex-factor. Po przydzieleniu miejsca Flexible sprawdza fit — jeśli jest loose, do elementu podrzędnego stosowane jest ograniczenie „nie więcej niż przydzielone”, pozwalając mu pozostać małym.

Cecha Flexible: jeśli widget podrzędny ma własne minimalne rozmiary (na przykład Text z długim łańcuchem znaków), Flexible przydziela mu żądane miejsce, a nie rozciąga go na siłę. To czyni Flexible niezastąpionym dla elementów, których rozmiar powinien być określany przez treść, a nie przez kontener.

Wniosek: używaj Flexible, gdy trzeba zarezerwować miejsce dla elementu, ale nie zmuszać go do rozciągania. To zachowuje naturalne rozmiary treści przy elastycznym rozmieszczeniu układu.

FlexFit.tight vs FlexFit.loose

FlexFit — wyliczenie z dwóch wartości: tight i loose. Od wyboru fit zależy, czy widget podrzędny zostanie przymusowo rozciągnięty do rozmiarów przydzielonego miejsca.

FlexFit.tight: element podrzędny otrzymuje tight constraints — minimalny i maksymalny rozmiar są równe przydzielonemu miejscu. Dziecko musi zająć dokładnie tyle miejsca, ile przydzielił Flex-algorytm. Jeśli dziecko jest mniejsze — zostaje rozciągnięte. Jeśli większe — zostaje ściśnięte. Zachowanie identyczne z Expanded.

FlexFit.loose: element podrzędny otrzymuje loose constraints — minimalny rozmiar wynosi 0, maksymalny jest równy przydzielonemu miejscu. Dziecko może być dowolnego rozmiaru od 0 do maximum. Jeśli dziecko jest małe (na przykład Text z krótkim łańcuchem znaków), zajmuje swoją naturalną szerokość, a reszta miejsca pozostaje pusta.

Wniosek: FlexFit.loose — wybór dla bloków tekstowych i elementów z naturalnym rozmiarem. FlexFit.tight — dla sztywnych układów kolumnowych, gdzie wszystkie elementy powinny być tej samej szerokości lub wysokości.

Kiedy używać Flexible zamiast Expanded

Flexible i Expanded wyglądają podobnie, ale rozwiązują różne zadania. Expanded zawsze rozciąga dziecko na pełną dostępną przestrzeń. Flexible może pozostawić puste miejsce wokół dziecka, jeśli rozmiar treści jest mniejszy niż przydzielona część.

Scenariusz dla Flexible: wewnątrz Row znajdują się dwa przyciski. Pierwszy — „Kup” (krótki tekst), drugi — „Dodaj do koszyka” (długi tekst). Z Expanded oba przyciski rozciągną się na równą szerokość, a krótki tekst będzie miał ogromne marginesy. Z Flexible każdy przycisk zajmie szerokość swojego tekstu, a wolne miejsce pozostanie pomiędzy nimi lub na brzegach.

Scenariusz dla Expanded: wewnątrz Column znajdują się trzy karty, które powinny zajmować równą wysokość niezależnie od zawartości. Expanded równomiernie dzieli dostępną wysokość, a każda karta rozciąga się do jednakowego rozmiaru. Flexible z loose tutaj nie zadziała — mała karta pozostanie mała, naruszając jednolity design.

Wniosek: wybieraj Flexible, gdy zawartość określa rozmiar elementu i puste miejsce wokół niego jest dopuszczalne. Wybieraj Expanded, gdy wszystkie elementy powinny być jednakowego rozmiaru niezależnie od treści.

Przykłady kodu z Flexible

Przykład 1 demonstruje podstawowe użycie Flexible z FlexFit.loose w Row.

dart
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.amber,
        child: const Text('krótki'),
      ),
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.cyan,
        child: const Text('długi tekst do demo'),
      ),
    ),
  ],
)

W przykładzie oba Flexible z loose fit. Pierwszy kontener z krótkim tekstem zajmuje swoją naturalną szerokość. Drugi z długim — swoją. Row przydziela każdemu połowę dostępnej szerokości, ale loose fit pozwala kontenerom być mniejszymi, a wolne miejsce pozostaje puste pomiędzy nimi.

Przykład 2 — porównanie Flexible z Tight i Loose fit w Column.

dart
Column(
  children: [
    Flexible(
      fit: FlexFit.tight,
      child: const Card(
        child: ListTile(
          title: Text('Tight — rozciągnięty na pełną wysokość'),
        ),
      ),
    ),
    const SizedBox(
      height: 8,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: const Card(
        child: ListTile(
          title: Text('Loose — naturalna wysokość'),
        ),
      ),
    ),
  ],
)

W Column pierwszy Flexible (tight) rozciąga Card na połowę dostępnej wysokości. Drugi Flexible (loose) — Card zajmuje wysokość według zawartości, a reszta miejsca pozostaje pusta. Wizualnie widać, jak tight wymusza wypełnienie obszaru, a loose zachowuje kompaktowy rozmiar.

Wniosek: w kodzie produkcyjnym Flexible z loose stosuje się do pól formularzy, przycisków i bloków tekstowych. Flexible z tight — odpowiednik Expanded, używany do równomiernego rozdzielania.

Typowe błędy przy używaniu Flexible

Błąd 1: użycie Flexible poza kontenerem Flex. Podobnie jak Expanded, Flexible zgłasza LayoutException, jeśli nie znajduje się wewnątrz Row, Column lub Flex. Rozwiązanie: zawsze sprawdzaj łańcuch rodzicielski widgetów.

Błąd 2: pomylenie Flexible i Expanded. Programiści często używają Expanded, gdy potrzebny jest Flexible z loose fit, i odwrotnie. Rezultat: Expanded rozciąga element z krótkim tekstem, tworząc duże puste pola. Rozwiązanie: jeśli rozmiar elementu może być mniejszy niż przydzielone miejsce — używaj Flexible(fit: FlexFit.loose).

Błąd 3: zerowy flex-factor. Flexible z flex=0 zachowuje się jak nieelastyczny widget, co może być nieoczywiste. Programista oczekuje elastycznego zachowania, ale element zajmuje minimalny rozmiar. Rozwiązanie: flex powinien być ≥1 do aktywnego rozdzielania przestrzeni.

Błąd 4: Flexible wewnątrz ScrollView bez ograniczenia rozmiaru. Jeśli Flexible znajduje się w Column wewnątrz SingleChildScrollView, scroll-kontener daje nieskończoną przestrzeń i flex-rozdział nie działa. Rozwiązanie: ogranicz rozmiar scroll-kontenera przez SizedBox lub ConstrainedBox.

Wniosek: Flexible wymaga takiej samej uwagi do kontekstu rodzicielskiego jak Expanded. Różnica tylko w fit — wybieraj go świadomie w zależności od zadania.

Często zadawane pytania

Czym się różni Flexible od Expanded?

Expanded — to Flexible z ustalonym fit=tight. Różnica polega na tym, że Expanded ma sztywne powiązanie z wypełnieniem całej dostępnej przestrzeni, podczas gdy Flexible może użyć loose fit do zachowania naturalnego rozmiaru dziecka.

Jaki fit wybrać dla przycisków w Row?

Dla przycisków z różną długością tekstu używaj Flexible(fit: FlexFit.loose). Każdy przycisk zajmie szerokość według zawartości i nie będzie między nimi dysproporcji. Expanded zrówna wszystkie przyciski do tej samej szerokości.

Jak sprawić, żeby Flexible zachowywał się jak Expanded?

Ustaw fit: FlexFit.tight — Flexible będzie zmuszać dziecko do wypełnienia całej przydzielonej przestrzeni. W tym trybie Flexible jest w pełni identyczny z Expanded pod względem zachowania.

Czy Flexible może zmniejszyć rozmiar dziecka?

Tak, jeśli dziecko jest większe niż przydzielone miejsce. Flexible przekazuje constraints z maksymalnym rozmiarem równym części Flex-kontenera. Jeśli dziecko przekracza ten rozmiar, zostaje ściśnięte w ramach constraints.

Czy Flexible działa bezpośrednio z Flex kontenerem?

Tak, Flexible działa z dowolnym kontenerem Flex, w tym Row, Column i podstawowym widgetem Flex z dowolnym direction. Flex pozwala zadawać niestandardowe kierunki przez mainAxisAlignment i crossAxisAlignment.

Podsumowanie

  • Flexible — widget do elastycznego rozdzielania przestrzeni bez wymuszonego rozciągania dziecka
  • FlexFit.loose zachowuje naturalny rozmiar zawartości, FlexFit.tight wymusza wypełnienie obszaru
  • Expanded — szczególny przypadek Flexible z fit=tight, używaj Flexible gdy potrzebny jest wybór fit
  • Flex-factor działa tak samo dla Flexible i Expanded — proporcja wolnego miejsca
  • Loose fit idealny dla przycisków, bloków tekstowych i elementów z dynamiczną zawartością
  • Zalecenie: stosuj Flexible z loose dla komponentów, których rozmiar jest określany przez treść

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.

Omów projekt

Przeczytaj również