Expanded: ce este și principiul de funcționare în Flutter

Autor: IT Sectr Publicat: 2026-07-03 Timp de citire: 6 min

Expanded este un widget Flutter care forțează elementul copil să ocupe tot spațiul disponibil într-un container Flex. Când Row sau Column distribuie spațiul între copii, Expanded preia spațiul liber după contabilizarea elementelor non-flexibile. Conform documentației oficiale Flutter (2026), Expanded este unul dintre cele mai utilizate widget-uri de layout: este folosit în procentarea interfețelor, construirea de carduri, liste și panouri. Principalul său avantaj este calculul automat al lățimii sau înălțimii pe baza coeficientului flex fără specificarea explicită a dimensiunilor.

Idei principale

  • Expanded — widget de layout care întinde copilul pe tot spațiul liber în Row, Column sau Flex
  • Factorul Flex determină ce parte din spațiul liber va primi fiecare Expanded
  • Expanded se deosebește de Flexible prin faptul că umple forțat tot spațiul disponibil
  • Stack nu suportă Expanded, doar Row, Column și Flex
  • Eroare la utilizarea Expanded în afara containerului Flex provoacă LayoutException

Ce este Expanded

Expanded este un widget-wrapper care primește un child și îl forțează să se extindă pentru a umple spațiul disponibil într-un container Flex (Row, Column, Flex). Expanded nu are reprezentare vizuală proprie — doar gestionează constrângerile transmise elementului copil.

La baza Expanded stă mecanismul Flex furnizat de framework-ul Flutter. Când Row sau Column calculează dimensiunile copiilor lor, mai întâi alocă spațiu elementelor non-flexibile (widget-uri obișnuite cu dimensiuni fixe), iar spațiul rămas îl distribuie între copiii Expanded și Flexible proporțional cu factorii lor flex.

Expanded folosește Flexible.fit = FlexFit.tight. Aceasta înseamnă că copilul Expanded trebuie să ocupe tot spațiul alocat, chiar dacă dimensiunea sa proprie este mai mică. Spre deosebire de Flexible cu Fit.loose, unde copilul poate fi mai mic decât zona alocată, Expanded forțează întinderea conținutului.

Concluzie: Expanded este instrumentul principal pentru crearea layout-urilor proporționale în Flutter. Folosiți-l când aveți nevoie ca un element să ocupe garantat toată lățimea sau înălțimea disponibilă.

Expanded vs Flexible: diferențe cheie

Expanded și Flexible — ambele distribuie spațiul în containere Flex, dar se comportă fundamental diferit. Diferența constă în proprietatea fit, care determină dacă copilul poate fi mai mic decât spațiul disponibil.

Expanded are un model de comportament rigid: fit-ul său este egal cu FlexFit.tight. Aceasta înseamnă că widget-ul copil primește constrângeri egale cu spațiul disponibil — nici mai mult, nici mai puțin. Dacă copilul este mai mic, este întins. Dacă este mai mare, este comprimat. Flexible folosește FlexFit.loose, permițând elementului copil să fie de orice dimensiune în limitele spațiului alocat.

În practică: dacă în interiorul Row se află două Expanded cu flex=1, fiecare va ocupa exact jumătate din lățime. Dacă le înlocuiți cu Flexible cu fit.loose, fiecare copil poate fi mai mic de jumătate, dacă dimensiunea sa proprie este mai mică — spațiul rămas va rămâne gol.

Concluzie: folosiți Expanded pentru layout-uri proporționale stricte, Flexible — când copilul poate fi mai mic decât spațiul disponibil. Dacă nu sunteți sigur — începeți cu Expanded, oferă un comportament mai predictibil.

Factorul Flex: cum este distribuit spațiul

Factorul Flex (parametrul flex) — o valoare numerică care determină partea din spațiul disponibil pe care o va primi Expanded. În mod implicit flex=1, ceea ce înseamnă distribuție egală între toți copiii Expanded.

Algoritmul de distribuție funcționează în trei pași. Primul: Flutter calculează intrinsic size al tuturor copiilor non-flexibili. Al doilea: spațiul rămas este împărțit la suma tuturor factorilor flex. Al treilea: fiecare Expanded primește o parte egală cu factorul său flex înmulțit cu dimensiunea unei unități de flex.

De exemplu, un Row cu lățimea de 300px conține două Expanded: primul cu flex=2, al doilea cu flex=1. Spațiul liber (300px minus copiii non-flexibili) este împărțit în 3 părți. Primul primește 2/3, al doilea — 1/3. Dacă nu există copii non-flexibili, primul va primi 200px, al doilea — 100px.

Factorul flex poate fi orice număr întreg pozitiv. Valoarea 0 este un caz special: Expanded cu flex=0 se comportă ca un widget non-flexibil obișnuit, ocupând spațiul minim după dimensiunea copilului. Acest comportament este echivalent cu absența Expanded.

Concluzie: factorul flex este cheia construirii layout-urilor flexibile. Folosiți proporții 1:1 pentru coloane egale, 2:1 pentru panouri cu zonă principală și laterală, 3:1 pentru interfețe cu navigare îngustă.

Exemple de cod cu Expanded

Exemplul 1 demonstrează utilizarea de bază a Expanded în Row pentru crearea a trei coloane egale.

dart
Row(
  children: [
    Expanded(
      child: Container(
        color: Colors.red,
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.green,
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.blue,
      ),
    ),
  ],
)

În acest exemplu, trei Expanded cu flex=1 (implicit) împart lățimea Row în mod egal. Containerele se întind pe toată înălțimea stabilită de Row și ocupă părți egale. Această abordare este convenabilă pentru crearea layout-urilor coloane cu distribuție proporțională.

Exemplul 2 arată utilizarea diferiților factori flex pentru crearea unui layout cu panou lateral și conținut principal.

dart
Row(
  children: [
    Expanded(
      flex: 1,
      child: Container(
        color: Colors.grey.200,
        child: const Center(
          child: Text('Panou lateral'),
        ),
      ),
    ),
    Expanded(
      flex: 3,
      child: Container(
        color: Colors.white,
        child: const Center(
          child: Text('Zona de conținut'),
        ),
      ),
    ),
  ],
)

Al doilea exemplu creează un layout tipic cu panou lateral (25%) și zonă principală (75%). flex=1 și flex=3 dau raportul 1:3. La modificarea lățimii ecranului, proporțiile se păstrează automat — aceasta este baza interfețelor adaptive.

Concluzie: Expanded cu diferiți factori flex este instrumentul standard pentru construirea layout-urilor adaptive. Combinarea Expanded în Column permite crearea atât a aranjamentelor proporționale orizontale, cât și verticale.

Erori tipice la utilizarea Expanded

Eroarea 1: utilizarea Expanded în afara Row, Column sau Flex. Dacă plasați Expanded direct în Stack, ListView sau alt container care nu este Flex, Flutter aruncă LayoutException cu mesajul „Expanded widgets must be placed inside Flex widgets”. Soluție: verificați widget-ul părinte — doar Row, Column sau Flex.

Eroarea 2: plasarea Expanded în interiorul ListView fără specificarea shrinkWrap. ListView în mod implicit are înălțime infinită în direcția de derulare, iar Expanded nu își poate calcula cota. Soluție: utilizați shrinkWrap: true sau înfășurați ListView într-un SizedBox cu înălțime fixă.

Eroarea 3: mai multe Expanded cu flex total care depășește spațiul disponibil. Dacă în interiorul Row cu lățime limitată se află Expanded, precum și widget-uri cu intrinsic size mare, poate apărea overflow. Soluție: verificați dimensiunile minime ale copiilor non-flexibili și, dacă este necesar, utilizați FittedBox sau Flex fit.

Eroarea 4: Expanded imbricate în Column în interiorul Row. Dacă Expanded în interiorul Column conține un alt Expanded în interiorul Row, poate apărea un conflict de constrângeri. Soluție: limitați adâncimea imbricării sau utilizați ConstrainedBox pentru specificarea explicită a dimensiunilor la nivelurile intermediare.

Concluzie: Expanded necesită contextul corect al părintelui. Verificați întotdeauna că Expanded se află direct în Row, Column sau Flex și evitați imbricarea fără dimensiuni explicite.

Întrebări frecvente

Cu ce se deosebește Expanded de SizedBox.expand?

SizedBox.expand forțează întinderea copilului la dimensiunile stabilite de constrângerile externe, dar nu participă la distribuția flex. Expanded funcționează doar în interiorul containerelor Flex și ia în considerare factorul flex la distribuirea spațiului liber între copii.

Se poate folosi Expanded în interiorul Stack?

Nu. Stack nu este un container Flex, iar utilizarea Expanded în interiorul său va provoca LayoutException. Pentru întinderea copiilor în Stack, utilizați Positioned.fill sau BoxConstraints.expand.

Ce se întâmplă dacă nu specific factorul flex?

În mod implicit flex=1. Toate Expanded fără flex explicit vor primi părți egale din spațiul liber. Dacă în Row sunt trei Expanded fără flex, fiecare va ocupa exact o treime din spațiul disponibil.

Cum fac Expanded doar pe lățime, dar nu pe înălțime?

Plasați Expanded în Row pentru întindere orizontală. Pentru întindere verticală, utilizați Expanded în interiorul Column. Dacă trebuie să limitați dimensiunile, înfășurați Expanded sau copilul său într-un SizedBox.

Funcționează Expanded cu Wrap sau widget-uri Flex?

Expanded funcționează cu Flex, inclusiv Row și Column ca subclase ale acestuia. Wrap nu este un container Flex și nu suportă Expanded. Pentru distribuirea spațiului în Wrap, folosiți alte metode, cum ar fi RunAlignment.

Rezumat

  • Expanded — widget pentru întinderea forțată a copilului pe tot spațiul disponibil într-un container Flex
  • Factorul Flex determină proporția de distribuție a spațiului liber între mai multe Expanded
  • Diferența de Flexible: Expanded folosește tight fit (umplere obligatorie), Flexible — loose fit (opțională)
  • Eroare la plasarea Expanded în afara Row, Column sau Flex provoacă LayoutException
  • Adaptabilitate: proporțiile layout-ului se păstrează automat la modificarea dimensiunii ecranului
  • Recomandare: folosiți Expanded ca instrument principal pentru layout-uri coloane și panouri în Flutter

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și