MediaQuery — obiect în Flutter care oferă informații despre mediul media curent: dimensiunea ecranului, orientarea dispozitivului, densitatea pixelilor, marginile sistemului și dimensiunea fontului. MediaQueryData — container pentru toate aceste metrici, accesibil prin MediaQuery.of(context). Conform documentației oficiale Flutter (2026), MediaQuery este baza designului adaptiv: prin el se determină dacă să se afișeze layout mobil sau tablet, se calculează marginile pentru safe area și se aleg dimensiunile elementelor față de ecran.
Principalele
MediaQuery — este un widget și o clasă Flutter care furnizează date despre mediul media al aplicației. MediaQuery înfășoară întreaga aplicație în widgetul rădăcină MaterialApp sau CupertinoApp, iar orice widget copil poate accesa aceste date prin MediaQuery.of(context).
Când Flutter lansează aplicația, creează o instanță MediaQueryData care conține toate metricele dispozitivului curent. Aceste date se actualizează automat la modificări: rotirea dispozitivului, schimbarea dimensiunii ferestrei (pe desktop), apariția tastaturii sau modificarea setărilor sistemului de accesibilitate. MediaQuery reconstruiește subarborele widgeturilor la orice modificare a datelor, asigurând adaptarea reactivă a interfeței.
MediaQueryData include: size (dimensiunea ecranului), devicePixelRatio (densitatea pixelilor), textScaleFactor (scala fontului din setările sistemului), viewInsets (zona acoperită de tastatură), viewPadding (marginile sistemului), orientation (orientarea) și platformBrightness (tema deschisă sau întunecată).
Concluzie: MediaQuery — sursa centrală de informații despre dispozitiv în Flutter. Accesul la MediaQuery.of(context) este primul pas în construirea oricărei interfețe adaptive.
MediaQueryData conține zeci de proprietăți, dar cele mai frecvent utilizate sunt cele care influențează construirea layout-ului. Să le analizăm pe cele cheie.
MediaQuery.of(context).size returnează un obiect Size cu lățimea și înălțimea ecranului în pixeli logici (device-independent pixels, dip). Aceste valori nu iau în considerare marginile sistemului. Pentru calculele layout-urilor adaptive, size este metrica principală: pe baza ei se determină breakpoints pentru layout mobil, tablet și desktop.
ViewPadding — marginile pe care sistemul le rezervă pentru bara de stare, notch (decupajul ecranului), panoul de navigare sistem și indicatorul de acasă (pe iOS). Fără luarea în considerare a acestor margini, conținutul poate ajunge sub elementele sistemului. MediaQuery.of(context).padding returnează EdgeInsets care trebuie aplicat ca padding containerului rădăcină al paginii.
ViewInsets — zona ecranului acoperită de tastatura software. Pentru câmpurile de intrare este critic să se urmărească viewInsets.bottom pentru a ridica conținutul deasupra tastaturii. Flutter gestionează automat acest lucru în scaffold, dar pentru layout-uri personalizate trebuie folosit direct MediaQuery.of(context).viewInsets.
Orientation — orientarea verticală (portrait) sau orizontală (landscape). Se determină prin compararea lățimii și înălțimii: dacă lățimea este mai mică decât înălțimea — portrait, altfel — landscape. În codul de producție, orientarea este folosită pentru comutarea între dispunerea verticală și orizontală a elementelor.
Concluzie: patru proprietăți cheie — size, viewPadding, viewInsets și orientation — acoperă 90% din sarcinile de design adaptiv. Celelalte proprietăți (textScaleFactor, platformBrightness, devicePixelRatio) sunt folosite în scenarii specifice.
MediaQuery — baza designului adaptiv în Flutter. Prin el se determină breakpoints, se comută layout-ul în funcție de dimensiunea ecranului și se ajustează marginile pentru diferite dispozitive.
Scenariu tipic: aplicația mobilă trebuie să afișeze o listă de produse. Pe telefon (lățime < 600dp) — o coloană. Pe tablet (lățime 600–900dp) — două coloane. Pe desktop (lățime > 900dp) — trei coloane. MediaQuery.of(context).size.width permite selectarea dinamică a numărului de coloane fără un ecran separat pentru fiecare form factor.
Al doilea scenariu: luarea în considerare a system gesture insets pe dispozitivele moderne. Pe iPhone cu Dynamic Island sau Android cu gesture navigation, marginile sistemului ocupă o parte din ecran. MediaQuery.of(context).padding returnează valori corecte pentru fiecare tip de dispozitiv, iar Scaffold le aplică automat prin body. Pentru widgeturi personalizate, padding-ul trebuie transmis explicit din MediaQuery.
Al treilea scenariu: adaptarea la setările sistemului de accesibilitate. MediaQuery.of(context).textScaleFactor arată cât de mult a mărit utilizatorul fontul în setări. La textScaleFactor > 1.3 layout-ul se poate strica — textele lungi ies din limitele cardurilor. Layout-urile adaptive trebuie să ia în considerare acest lucru și, la nevoie, să comute la un layout mai simplu.
Concluzie: MediaQuery — nu doar o sursă de metrici, ci un instrument pentru construirea interfețelor cu adevărat adaptive. Folosește-l pentru breakpoints, safe area și luarea în considerare a accesibilității.
Exemplul 1 demonstrează obținerea dimensiunii ecranului și aplicarea breakpoints pentru selectarea numărului de coloane.
int getColumnCount(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width > 900) return 3;
if (width > 600) return 2;
return 1;
}
Exemplul de mai sus arată o funcție de selectare a numărului de coloane pe baza lățimii ecranului. Breakpoints 600 și 900 corespund standardelor comune Material Design pentru telefoane, tablete și desktop.
Exemplul 2 — utilizarea MediaQuery cu viewPadding pentru plasarea corectă a conținutului cu luarea în considerare a marginilor sistemului.
Widget build(BuildContext context) {
final padding = MediaQuery.of(context).padding;
return Padding(
padding: EdgeInsets.only(
top: padding.top,
left: padding.left,
right: padding.right,
),
child: const MyContent(),
);
}
În acest exemplu, padding înfășoară conținutul în Padding, folosind marginile sistemului. top ia în considerare bara de stare și notch-ul, left/right — zonele sigure. bottom nu este inclus deoarece Scaffold gestionează de obicei singur navigarea de jos.
Exemplul 3 — determinarea orientării și schimbarea dispunerii elementelor.
Widget build(BuildContext context) {
final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
return isPortrait
? const Column(
children: [HeaderBanner(), ContentList()],
)
: const Row(
children: [HeaderBanner(), ContentList()],
);
}
În portrait mode elementele sunt dispuse vertical (Column), în landscape — orizontal (Row). Această abordare oferă cea mai bună utilizare a spațiului la rotirea dispozitivului.
Concluzie: MediaQuery — instrumentul principal pentru construirea layout-urilor adaptive. Ia întotdeauna în considerare marginile sistemului, breakpoints și orientarea la dezvoltarea interfețelor Flutter.
Eroarea 1: apelarea MediaQuery.of(context) în afara contextului unde este setat MediaQuery. Dacă widgetul se află deasupra MediaQuery în arbore, apelul duce la o eroare de execuție. Soluție: apelează întotdeauna MediaQuery.of(context) în interiorul widgeturilor înfășurate în MaterialApp sau CupertinoApp, unde MediaQuery este setat ca widget rădăcină.
Eroarea 2: uitarea de safe area. Dezvoltatorii folosesc MediaQuery.size pentru plasarea elementelor fără a lua în considerare marginile sistemului. Pe dispozitivele cu notch sau gesture navigation, conținutul ajunge sub bara de stare. Soluție: scade MediaQuery.of(context).padding din coordonatele de poziționare.
Eroarea 3: atașarea rigidă la dimensiuni. Folosirea MediaQuery.of(context).size.width pentru stabilirea dimensiunilor exacte ale elementelor (width: size.width * 0.3) funcționează doar pe dispozitive de același form factor. Pe desktop sau tablet, layout-ul arată nenatural. Soluție: folosește breakpoints în combinație cu Expanded și Flexible pentru un layout flexibil, nu procente rigide.
Eroarea 4: ignorarea textScaleFactor. La mărirea fontului sistemului de către utilizator, interfața se poate strica — textele ies din limitele containerelor. Soluție: verifică MediaQuery.of(context).textScaleFactor și la valori peste 1.3 comută layout-ul la o versiune mai simplă cu derulare.
Concluzie: MediaQuery — un instrument puternic, dar subtil. Ia în considerare marginile sistemului, orientarea și setările de accesibilitate pentru ca interfața să arate corect pe toate dispozitivele.
Întrebări frecvente
MediaQuery.size — dimensiunea totală a ecranului sau ferestrei aplicației în pixeli logici. MediaQuery.viewInsets — zona acoperită de tastatura sistemului. Pentru calculul spațiului disponibil fără tastatură: size.height - viewInsets.bottom.
LayoutBuilder oferă dimensiunile containerului părinte, nu ale ecranului în ansamblu. Folosește LayoutBuilder când dimensiunile widgetului depind de spațiul disponibil în interiorul unui părinte specific, iar MediaQuery — când ai nevoie de metrici globale ale ecranului.
Automat. La rotirea dispozitivului, Flutter actualizează MediaQueryData și reconstruiește subarborele. Proprietatea orientation se modifică, iar builder-ul tuturor widgeturilor abonate este apelat cu noile date.
Da. Înfășurând o parte din widgeturi în MediaQuery cu date suprascrise prin MediaQuery.removePadding, MediaQuery.removeViewInsets sau MediaQuery cu un alt Data. Acest lucru se aplică pentru încorporarea în iframe sau moduri de previzualizare.
Pentru teste, Flutter oferă setScreenSize și înveliș MediaQuery în mediul de testare. Pentru widget-teste, înfășoară componentul testat în MaterialApp sau MediaQuery cu date de test pentru a controla dimensiunile ecranului.
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