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 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 ș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 (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ă.
Exemplul 1 demonstrează utilizarea de bază a Expanded în Row pentru crearea a trei coloane egale.
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.
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.
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
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.
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.
Î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.
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.
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
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.
Citiți și