MediaQuery è un oggetto in Flutter che fornisce informazioni sull'ambiente multimediale corrente: dimensioni dello schermo, orientamento del dispositivo, densità di pixel, margini di sistema e dimensione del carattere. MediaQueryData è un contenitore per tutte queste metriche, accessibile tramite MediaQuery.of(context). Secondo la documentazione ufficiale di Flutter (2026), MediaQuery è la base del design adattivo: attraverso di esso si determina se visualizzare il layout mobile o tablet, calcolare i margini per l'area sicura e selezionare le dimensioni degli elementi relative allo schermo.
Punti chiave
MediaQuery è un widget e una classe in Flutter che fornisce dati sull'ambiente multimediale dell'applicazione. MediaQuery avvolge l'intera applicazione nel widget radice MaterialApp o CupertinoApp, e qualsiasi widget figlio può accedere a questi dati tramite MediaQuery.of(context).
Quando Flutter avvia un'applicazione, crea un'istanza di MediaQueryData contenente tutte le metriche del dispositivo corrente. Questi dati vengono aggiornati automaticamente ai cambiamenti: rotazione del dispositivo, ridimensionamento della finestra (su desktop), comparsa della tastiera o modifica delle impostazioni di accessibilità del sistema. MediaQuery ricostruisce il sottoalbero dei widget a qualsiasi cambiamento dei dati, fornendo un adattamento reattivo dell'interfaccia.
MediaQueryData include: size (dimensione dello schermo), devicePixelRatio (densità di pixel), textScaleFactor (scala del carattere dalle impostazioni di sistema), viewInsets (area coperta dalla tastiera), viewPadding (margini di sistema), orientation (orientamento) e platformBrightness (tema chiaro o scuro).
In sintesi: MediaQuery è la fonte centrale di informazioni sul dispositivo in Flutter. Accedere a MediaQuery.of(context) è il primo passo per costruire qualsiasi interfaccia adattiva.
MediaQueryData contiene decine di proprietà, ma le più utilizzate sono quelle che influenzano la costruzione del layout. Vediamo le principali.
MediaQuery.of(context).size restituisce un oggetto Size con larghezza e altezza dello schermo in pixel indipendenti dal dispositivo (dip). Questi valori non tengono conto dei margini di sistema. Per i calcoli di layout adattivo, size è la metrica principale: determina i punti di interruzione per layout mobile, tablet e desktop.
ViewPadding sono i margini che il sistema riserva per la barra di stato, il notch (ritaglio dello schermo), il pannello di navigazione di sistema e l'indicatore home (su iOS). Senza tenere conto di questi margini, il contenuto può apparire sotto gli elementi di sistema. MediaQuery.of(context).padding restituisce un EdgeInsets che deve essere applicato come padding al contenitore radice della pagina.
ViewInsets è l'area dello schermo coperta dalla tastiera software. Per i campi di input, è fondamentale monitorare viewInsets.bottom per sollevare il contenuto sopra la tastiera. Flutter gestisce questo automaticamente nello scaffold, ma per layout personalizzati è necessario utilizzare direttamente MediaQuery.of(context).viewInsets.
Orientation — orientamento verticale (portrait) o orizzontale (landscape). Viene determinato confrontando larghezza e altezza: se la larghezza è minore dell'altezza — portrait, altrimenti — landscape. Nel codice di produzione, l'orientamento viene utilizzato per passare dalla disposizione verticale a quella orizzontale degli elementi.
In sintesi: quattro proprietà chiave — size, viewPadding, viewInsets e orientation — coprono il 90% delle attività di progettazione adattiva. Le restanti proprietà (textScaleFactor, platformBrightness, devicePixelRatio) vengono utilizzate per scenari specifici.
MediaQuery è la base del design adattivo in Flutter. Attraverso di esso si determinano i punti di interruzione, si cambia il layout in base alla dimensione dello schermo e si regolano i margini per diversi dispositivi.
Scenario tipico: un'applicazione mobile deve mostrare un elenco di prodotti. Sul telefono (larghezza < 600dp) — una colonna. Sul tablet (larghezza 600–900dp) — due colonne. Sul desktop (larghezza > 900dp) — tre colonne. MediaQuery.of(context).size.width consente di selezionare dinamicamente il numero di colonne senza uno schermo separato per ogni fattore di forma.
Secondo scenario: tenere conto dei margini di gesti di sistema sui dispositivi moderni. Su iPhone con Dynamic Island o Android con navigazione gestuale, i margini di sistema consumano parte dello schermo. MediaQuery.of(context).padding restituisce valori corretti per ogni tipo di dispositivo e Scaffold li applica automaticamente tramite body. Per widget personalizzati, è necessario passare esplicitamente il padding da MediaQuery.
Terzo scenario: adattamento alle impostazioni di accessibilità del sistema. MediaQuery.of(context).textScaleFactor mostra quanto l'utente ha aumentato la dimensione del carattere nelle impostazioni. Con textScaleFactor > 1.3, il layout potrebbe rompersi — i testi lunghi superano i limiti delle schede. I layout adattivi dovrebbero tenerne conto e, se necessario, passare a un layout più semplice.
In sintesi: MediaQuery non è solo una fonte di metriche, ma uno strumento per costruire interfacce veramente adattive. Usalo per punti di interruzione, area sicura e considerazioni di accessibilità.
Esempio 1 mostra come ottenere la dimensione dello schermo e applicare punti di interruzione per selezionare il numero di colonne.
int getColumnCount(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width > 900) return 3;
if (width > 600) return 2;
return 1;
}
L'esempio sopra mostra una funzione per selezionare il numero di colonne in base alla larghezza dello schermo. I punti di interruzione 600 e 900 corrispondono agli standard generalmente accettati di Material Design per telefoni, tablet e desktop.
Esempio 2 — utilizzo di MediaQuery con viewPadding per il corretto posizionamento del contenuto considerando i margini di sistema.
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(),
);
}
In questo esempio, padding avvolge il contenuto in Padding utilizzando i margini di sistema. top tiene conto della barra di stato e del notch, left/right delle aree sicure. bottom non è incluso perché Scaffold gestisce solitamente la navigazione inferiore da solo.
Esempio 3 — determinazione dell'orientamento e cambio di disposizione degli elementi.
Widget build(BuildContext context) {
final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
return isPortrait
? const Column(
children: [HeaderBanner(), ContentList()],
)
: const Row(
children: [HeaderBanner(), ContentList()],
);
}
In modalità verticale, gli elementi sono disposti verticalmente (Column); in modalità orizzontale, orizzontalmente (Row). Questo approccio sfrutta al meglio lo spazio durante la rotazione del dispositivo.
In sintesi: MediaQuery è lo strumento principale per costruire layout adattivi. Tieni sempre conto dei margini di sistema, dei punti di interruzione e dell'orientamento durante lo sviluppo di interfacce Flutter.
Errore 1: chiamare MediaQuery.of(context) al di fuori di un contesto in cui MediaQuery è impostato. Se un widget è al di sopra di MediaQuery nell'albero, la chiamata causa un errore di runtime. Soluzione: chiamare sempre MediaQuery.of(context) all'interno di widget avvolti da MaterialApp o CupertinoApp, dove MediaQuery è impostato come widget radice.
Errore 2: dimenticare l'area sicura. Gli sviluppatori usano MediaQuery.size per posizionare elementi senza considerare i margini di sistema. Su dispositivi con notch o navigazione gestuale, il contenuto finisce sotto la barra di stato. Soluzione: sottrarre MediaQuery.of(context).padding dalle coordinate di posizionamento.
Errore 3: legame rigido alle dimensioni. Usare MediaQuery.of(context).size.width per impostare dimensioni esatte degli elementi (width: size.width * 0.3) funziona solo su dispositivi dello stesso fattore di forma. Sul desktop o tablet, il layout appare poco naturale. Soluzione: utilizzare punti di interruzione in combinazione con Expanded e Flexible per un layout flessibile, non percentuali fisse.
Errore 4: ignorare textScaleFactor. Quando l'utente aumenta il carattere di sistema, l'interfaccia può rompersi — i testi superano i limiti dei contenitori. Soluzione: controllare MediaQuery.of(context).textScaleFactor e per valori superiori a 1.3 passare a un layout più semplice con scorrimento.
In sintesi: MediaQuery è uno strumento potente ma delicato. Considera i margini di sistema, l'orientamento e le impostazioni di accessibilità per garantire che l'interfaccia appaia corretta su tutti i dispositivi.
Domande frequenti
MediaQuery.size è la dimensione totale dello schermo o della finestra dell'applicazione in pixel logici. MediaQuery.viewInsets è l'area coperta dalla tastiera di sistema. Per calcolare lo spazio disponibile senza tastiera: size.height - viewInsets.bottom.
LayoutBuilder fornisce le dimensioni del contenitore genitore, non dell'intero schermo. Usa LayoutBuilder quando le dimensioni dei widget dipendono dallo spazio disponibile all'interno di un genitore specifico e MediaQuery quando servono metriche globali dello schermo.
Automaticamente. Quando il dispositivo ruota, Flutter aggiorna MediaQueryData e ricostruisce il sottoalbero. La proprietà orientation cambia e il costruttore di tutti i widget sottoscritti viene chiamato con i nuovi dati.
Sì. Avvolgendo una parte dei widget in MediaQuery con dati sovrascritti tramite MediaQuery.removePadding, MediaQuery.removeViewInsets o MediaQuery con altri Data. Questo viene utilizzato per l'incorporamento in iframe o modalità di anteprima.
Per i test, Flutter fornisce setScreenSize e un wrapper MediaQuery nell'ambiente di test. Per i test dei widget, avvolgi il componente in test in MaterialApp o MediaQuery con dati di test per controllare le dimensioni dello schermo.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche