Skip to Content
FlutterLezione 2 Widget Di Base2.4 Responsive Design in Flutter

Responsive Design in Flutter

Descrizione

Flutter offre strumenti per creare interfacce utente responsive che si adattano a diverse dimensioni di schermo, orientamenti e dispositivi.

Widget chiave per il design responsive

  • MediaQuery: Fornisce informazioni sulle dimensioni dello schermo e sull’orientamento.
  • LayoutBuilder: Permette di costruire layout basati sulle dimensioni del widget genitore.
  • Flexible e Expanded: Gestiscono la distribuzione dello spazio all’interno di Row e Column.
  • FittedBox: Ridimensiona il contenuto mantenendo le proporzioni.
  • AspectRatio: Mantiene un rapporto di aspetto fisso.
  • FractionallySizedBox: Ridimensiona un widget come frazione dello spazio disponibile.

Widget chiave per il design responsive

1. MediaQuery

MediaQuery fornisce informazioni sulle dimensioni dello schermo e sull’orientamento. È utile per ottenere larghezza, altezza e altre metriche del dispositivo.

Esempio:

double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height;

2. LayoutBuilder

LayoutBuilder costruisce layout in base alle dimensioni del widget genitore. È ideale per adattare i widget a contesti specifici, evitando calcoli inutili con MediaQuery.

Esempio:

LayoutBuilder( builder: (context, constraints) { return Container( width: constraints.maxWidth * 0.5, height: 60, color: Colors.orange, ); }, )

3. Flexible e Expanded

  • Flexible: Distribuisce lo spazio disponibile in base al flex.
  • Expanded: Occupa tutto lo spazio disponibile assegnato.

Esempio:

Row( children: [ Flexible( flex: 1, child: Container(color: Colors.red), ), Expanded( flex: 2, child: Container(color: Colors.green), ), ], )

4. FittedBox

FittedBox ridimensiona il contenuto mantenendo le proporzioni.

Esempio:

Container( width: 200, height: 100, child: FittedBox( child: Text('Testo Ridimensionato'), ), )

5. AspectRatio

AspectRatio mantiene un rapporto fisso tra larghezza e altezza.

Esempio:

AspectRatio( aspectRatio: 16 / 9, child: Container(color: Colors.blue), )

6. FractionallySizedBox

FractionallySizedBox ridimensiona un widget come frazione dello spazio disponibile.

Esempio:

FractionallySizedBox( widthFactor: 0.8, heightFactor: 0.3, child: Container(color: Colors.yellow), )

Best Practices per il Responsive Design

  1. Evita di usare MediaQuery in modo eccessivo: Usa LayoutBuilder per layout flessibili e dinamici.
  2. Gestisci overflow in modo controllato: Usa SingleChildScrollView in spazi ridotti.
  3. Verifica il comportamento su schermi piccoli: Riduci la grandezza di font e spazi.
  4. Utilizza proporzioni anziché dimensioni fisse: Preferisci Flexible e FractionallySizedBox.
  5. Usa AspectRatio per contenuti multimediali: Mantiene proporzioni corrette su diversi schermi.

Codice di confronto varie modalità

import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Responsive Width & Height')), body: const ResponsiveExample(), ), ); } } class ResponsiveExample extends StatelessWidget { const ResponsiveExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; final screenHeight = MediaQuery.of(context).size.height; return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Screen Width: $screenWidth logical pixels'), Text('Screen Height: $screenHeight logical pixels'), const SizedBox(height: 16), // Container con dimensioni fisse in logical pixels Container( width: 100, height: 100, color: Colors.blue, child: const Center(child: Text('100x100 px')), ), const SizedBox(height: 16), // Container responsivo in base alla percentuale dello schermo Container( width: screenWidth * 0.5, // 50% della larghezza dello schermo height: screenHeight * 0.1, // 10% dell'altezza dello schermo color: Colors.green, child: const Center(child: Text('50% Width & 10% Height')), ), const SizedBox(height: 16), // Uso di LayoutBuilder per adattare il layout al contesto parent LayoutBuilder( builder: (context, constraints) { return Container( width: constraints.maxWidth * 0.7, // 70% della larghezza del parent height: 60, color: Colors.orange, child: const Center(child: Text('70% of parent width')), ); }, ), const SizedBox(height: 16), // Uso di FractionallySizedBox con Flexible Flexible( flex: 1, child: FractionallySizedBox( widthFactor: 0.8, // 80% della larghezza del parent heightFactor: 0.2, // 20% dell'altezza del parent child: Container( color: Colors.red, child: const Center( child: Text('Flexible + FractionallySizedBox'), ), ), ), ), const SizedBox(height: 16), // Uso di Expanded con FractionallySizedBox Expanded( child: FractionallySizedBox( widthFactor: 0.8, // 80% della larghezza del parent heightFactor: 0.2, // 20% dell'altezza del parent child: Container( color: Colors.purple, child: const Center( child: Text('Expanded + FractionallySizedBox'), ), ), ), ), ], ), ); } }