[{"data":1,"prerenderedAt":78},["ShallowReactive",2],{"tutorial-hot-reload-e-widget-inspector-debuggare-la-ui-flutter-con-i-devtools":3,"comments-tutorial-hot-reload-e-widget-inspector-debuggare-la-ui-flutter-con-i-devtools":77},{"id":4,"title":5,"slug":6,"excerpt":7,"intro":8,"cover_image":9,"cover_remote_url":10,"cover_credit":11,"video_url":15,"video":16,"difficulty":20,"estimated_minutes":21,"flutter_version":22,"status":23,"published_at":24,"meta_title":25,"meta_description":26,"category":27,"author":31,"steps":33},78,"Hot reload e Widget Inspector: debuggare la UI Flutter con i DevTools","hot-reload-e-widget-inspector-debuggare-la-ui-flutter-con-i-devtools","Impara a usare hot reload, hot restart e il Widget Inspector dei Flutter DevTools per costruire e correggere le interfacce in tempo reale, senza ricompilare l'app a ogni modifica.","Uno dei motivi per cui Flutter è così amato è la velocità del ciclo di sviluppo: modifichi il codice, salvi e in meno di un secondo vedi il risultato sul dispositivo. Questa magia si chiama **hot reload**.\n\nMa hot reload da solo non basta: quando un layout non si comporta come previsto (un `Container` che non si colora, un testo che va in overflow, uno spazio che non capisci da dove arrivi) hai bisogno di uno strumento che ti mostri l'**albero dei widget** e le loro proprietà reali a runtime. È il compito del **Widget Inspector**, incluso nei **Flutter DevTools**.\n\nIn questo tutorial per principianti vedremo:\n\n- la differenza tra **hot reload**, **hot restart** e **full restart**;\n- quando hot reload *non* funziona e perché;\n- come aprire i **DevTools** da VS Code, Android Studio e da terminale;\n- come usare il **Widget Inspector**, il **Select Widget Mode**, il **Layout Explorer** e le guide di debug (`debugPaintSizeEnabled`, Slow Animations, Highlight Repaints).\n\nAlla fine avrai un metodo pratico per capire *cosa* sta realmente disegnando la tua app, invece di procedere per tentativi.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F2c4c7ac3-6cbe-4b7f-a357-6eaf4dc356be.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1599338838409-c6ccdf0c5ef9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3ODc5Nzc4ODR8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"Will Ulmer","https:\u002F\u002Funsplash.com\u002F@willulmer","https:\u002F\u002Funsplash.com\u002Fphotos\u002Fblack-laptop-computer-turned-on-displaying-microsoft-word--R-mVjSc828","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Kuv00WDp_sU",{"youtube_id":17,"duration_seconds":18,"published_at":19},"Kuv00WDp_sU",107,"2026-08-29T11:26:46+00:00","beginner",30,"3.x","published","2026-08-29T04:31:25+00:00","Hot reload e Widget Inspector nei Flutter DevTools","Guida beginner a hot reload, hot restart e Widget Inspector dei Flutter DevTools: debug del layout, Layout Explorer e strumenti di ispezione della UI.",{"id":28,"name":29,"slug":30},1,"Guide","guide",{"id":28,"name":32},"Flutter Bot",[34,42,49,57,63,70],{"id":35,"position":28,"title":36,"body":37,"code_snippet":38,"code_language":39,"expected_result":40,"demo_url":41,"video_url":41},521,"Preparare un progetto di prova con un layout \"sbagliato\"","Creiamo un progetto nuovo e sostituiamo il contenuto di `lib\u002Fmain.dart` con una schermata semplice, che useremo come cavia per gli esperimenti.\n\n```bash\nflutter create devtools_demo\ncd devtools_demo\nflutter run\n```\n\nIl codice qui sotto mostra una card con avatar, titolo e descrizione. Il testo del sottotitolo è volutamente lungo: più avanti lo useremo per generare (e risolvere) un errore di overflow.\n\nAvvia l'app con `flutter run` da terminale, oppure con il tasto **Run\u002FDebug** del tuo IDE: è importante avviarla in **modalità debug**, perché hot reload e DevTools non funzionano in release.","import 'package:flutter\u002Fmaterial.dart';\n\nvoid main() => runApp(const MyApp());\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'DevTools Demo',\n      theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true),\n      home: const HomePage(),\n    );\n  }\n}\n\nclass HomePage extends StatefulWidget {\n  const HomePage({super.key});\n\n  @override\n  State\u003CHomePage> createState() => _HomePageState();\n}\n\nclass _HomePageState extends State\u003CHomePage> {\n  int _contatore = 0;\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('DevTools Demo')),\n      body: Center(\n        child: Card(\n          margin: const EdgeInsets.all(16),\n          child: Padding(\n            padding: const EdgeInsets.all(16),\n            child: Row(\n              children: [\n                const CircleAvatar(radius: 28, child: Icon(Icons.person)),\n                const SizedBox(width: 16),\n                Column(\n                  crossAxisAlignment: CrossAxisAlignment.start,\n                  mainAxisSize: MainAxisSize.min,\n                  children: [\n                    const Text('Mario Rossi',\n                        style: TextStyle(fontSize: 20)),\n                    Text('Hai premuto il bottone $_contatore volte'),\n                  ],\n                ),\n              ],\n            ),\n          ),\n        ),\n      ),\n      floatingActionButton: FloatingActionButton(\n        onPressed: () => setState(() => _contatore++),\n        child: const Icon(Icons.add),\n      ),\n    );\n  }\n}","dart","L'app parte in modalità debug e mostra una card centrata con avatar, nome e contatore; il FAB incrementa il numero.",null,{"id":43,"position":44,"title":45,"body":46,"code_snippet":47,"code_language":39,"expected_result":48,"demo_url":41,"video_url":41},522,2,"Usare hot reload e capire la differenza con hot restart","Con l'app in esecuzione, premi il FAB 3 volte: il contatore arriva a 3. Ora **modifica il colore del tema** e salva.\n\n- In VS Code \u002F Android Studio basta **salvare il file** (`Ctrl+S` \u002F `Cmd+S`): l'hot reload parte da solo.\n- Da terminale, nella console dove gira `flutter run`, premi il tasto **`r`**.\n\nNoterai due cose fondamentali:\n\n1. La UI si aggiorna in meno di un secondo.\n2. **Il contatore resta a 3**: lo stato dell'app è conservato.\n\nÈ questa la differenza chiave:\n\n| Comando | Tasto | Cosa fa | Stato |\n|---|---|---|---|\n| **Hot reload** | `r` | Inietta il nuovo codice e ricostruisce i widget | **Conservato** |\n| **Hot restart** | `R` | Ricarica l'app da zero mantenendo il processo | **Azzerato** |\n| **Full restart** | stop + run | Ricompila tutto (nativo incluso) | Azzerato |\n\n### Quando hot reload NON basta\n\nDevi usare **hot restart** (o riavviare del tutto) quando:\n\n- cambi il codice di `main()` o gli inizializzatori di variabili `static`\u002Fglobali;\n- modifichi lo stato iniziale in `initState()` e vuoi rivederlo eseguire;\n- cambi il tipo di un widget (da `StatelessWidget` a `StatefulWidget`);\n- aggiungi o modifichi **enum**, gerarchie di classi o generici in modo strutturale.\n\nServe invece uno **stop e run completo** quando:\n\n- aggiungi un pacchetto con codice nativo in `pubspec.yaml`;\n- modifichi asset dichiarati nel `pubspec.yaml` (a volte basta hot restart);\n- tocchi file nativi in `android\u002F` o `ios\u002F`.\n\nProva tu: cambia il valore iniziale in `int _contatore = 100;`, salva (hot reload) e osserva che *non* cambia nulla. Premi ora `R` (hot restart) e vedrai `100`.","\u002F\u002F Prova 1 -> hot reload: la UI cambia colore, il contatore resta invariato\ntheme: ThemeData(colorSchemeSeed: Colors.deepOrange, useMaterial3: true),\n\n\u002F\u002F Prova 2 -> hot reload NON ha effetto, serve hot restart (tasto R)\nint _contatore = 100;","Con hot reload cambiano i colori senza perdere il contatore; con hot restart l'app riparte dal nuovo valore iniziale.",{"id":50,"position":51,"title":52,"body":53,"code_snippet":54,"code_language":55,"expected_result":56,"demo_url":41,"video_url":41},523,3,"Aprire i DevTools e il Widget Inspector","I **Flutter DevTools** sono una suite di strumenti web (Inspector, Performance, Memory, Network, Logging) inclusa nell'SDK: non devi installare nulla.\n\n### Da VS Code\n1. Avvia l'app in debug.\n2. `Ctrl+Shift+P` \u002F `Cmd+Shift+P` → **\"Flutter: Open DevTools\"** → scegli *Open in Browser* o *Widget Inspector*.\n\n### Da Android Studio \u002F IntelliJ\n1. Avvia l'app in debug.\n2. Nella barra della finestra **Flutter Inspector** (a destra) o dal pulsante **Open DevTools** nella toolbar di esecuzione.\n\n### Da terminale\nQuando lanci `flutter run`, la console stampa un URL simile a:\n\n```\nA Dart VM Service on sdk gphone64 is available at: http:\u002F\u002F127.0.0.1:52341\u002FAbCdEf=\u002F\nThe Flutter DevTools debugger and profiler is available at:\nhttp:\u002F\u002F127.0.0.1:9101?uri=http:\u002F\u002F127.0.0.1:52341\u002FAbCdEf=\u002F\n```\n\nApri il secondo link nel browser. In alternativa premi **`v`** nella console di `flutter run`.\n\nUna volta dentro, seleziona la scheda **Flutter Inspector**: a sinistra vedrai l'**albero dei widget** della tua app, a destra i **dettagli** del widget selezionato (constraints, dimensioni, proprietà di rendering).","# Avvia l'app e apri i DevTools dal terminale\nflutter run\n\n# Tasti utili nella console di flutter run:\n#   r  -> hot reload\n#   R  -> hot restart\n#   v  -> apre i DevTools nel browser\n#   p  -> mostra\u002Fnasconde le guide di debug del layout\n#   o  -> alterna piattaforma Android\u002FiOS\n#   q  -> esce","bash","I DevTools si aprono nel browser (o nell'IDE) e la scheda Flutter Inspector mostra l'albero dei widget dell'app in esecuzione.",{"id":58,"position":59,"title":60,"body":61,"code_snippet":41,"code_language":39,"expected_result":62,"demo_url":41,"video_url":41},524,4,"Individuare un widget con il Select Widget Mode","Il **Select Widget Mode** è la funzione più utile per chi inizia: ti permette di **toccare un elemento sullo schermo dell'app** e vedere immediatamente **quale widget lo disegna** nell'albero.\n\nCome si usa:\n\n1. Nei DevTools, clicca l'icona **Select Widget Mode** (il cursore con il riquadro) in alto a sinistra nell'Inspector.\n2. Tocca l'avatar della card sul dispositivo\u002Femulatore.\n3. Nell'albero verrà evidenziato il `CircleAvatar`, e nel pannello di destra vedrai le sue proprietà e la catena di genitori (`Row` → `Padding` → `Card` → `Center` → ...).\n\nSuggerimenti pratici:\n\n- Il pulsante **\"Show Implementation Widgets\"** (o la spunta relativa) mostra anche i widget interni del framework: tienilo spento all'inizio per non perderti.\n- Selezionando un widget nell'albero, con il pulsante di **navigazione al sorgente** l'IDE salta direttamente alla riga di codice che lo crea.\n- La sezione **Details Tree \u002F Render Object** ti mostra `size` e `constraints` reali: è oro puro per capire perché un widget è più grande o più piccolo del previsto.\n\nProva a selezionare il `Text('Mario Rossi')` e leggi le sue dimensioni effettive: capirai subito quanto spazio occupa davvero.","Toccando un elemento dell'app, il widget corrispondente viene evidenziato nell'albero dei DevTools con tutte le sue proprietà.",{"id":64,"position":65,"title":66,"body":67,"code_snippet":68,"code_language":39,"expected_result":69,"demo_url":41,"video_url":41},525,5,"Risolvere un overflow con il Layout Explorer","Ora provochiamo l'errore più comune per chi inizia: la famosa striscia gialla e nera **\"RIGHT OVERFLOWED BY X PIXELS\"**.\n\nSostituisci il testo del sottotitolo con una frase lunga e salva (hot reload):\n\n```dart\nText('Sviluppatore Flutter con una passione smisurata per i layout complessi'),\n```\n\nLa `Column` dentro la `Row` cerca di occupare la larghezza del testo, ma non c'è spazio: overflow.\n\n### Diagnosticare con il Layout Explorer\n1. Con il **Select Widget Mode**, seleziona la `Row`.\n2. Apri la scheda **Layout Explorer** (accanto ai dettagli).\n3. Vedrai una rappresentazione grafica di `Row`\u002F`Column` con: larghezze dei figli, `flex`, `mainAxisAlignment` e `crossAxisAlignment` modificabili **al volo**.\n4. Il figlio che sfora è evidenziato in giallo\u002Frosso.\n\n### La soluzione\nBasta avvolgere la `Column` in un `Expanded`: le dice \"prendi tutto lo spazio orizzontale rimasto, non di più\". Aggiungiamo anche `maxLines` e `overflow: TextOverflow.ellipsis` per un troncamento elegante.\n\nSalva (hot reload) e l'errore scompare istantaneamente.\n\n> Nota: nel Layout Explorer puoi cambiare `mainAxisAlignment` con un menu a tendina e vedere l'effetto in tempo reale sull'app. È il modo più veloce per imparare come funzionano `Row` e `Column`.","Row(\n  children: [\n    const CircleAvatar(radius: 28, child: Icon(Icons.person)),\n    const SizedBox(width: 16),\n    Expanded( \u002F\u002F \u003C-- risolve l'overflow\n      child: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        mainAxisSize: MainAxisSize.min,\n        children: [\n          const Text('Mario Rossi', style: TextStyle(fontSize: 20)),\n          Text(\n            'Sviluppatore Flutter con una passione smisurata per i layout complessi',\n            maxLines: 2,\n            overflow: TextOverflow.ellipsis,\n          ),\n        ],\n      ),\n    ),\n  ],\n)","La striscia gialla e nera di overflow sparisce e il testo lungo viene troncato con i puntini di sospensione su due righe.",{"id":71,"position":72,"title":73,"body":74,"code_snippet":75,"code_language":39,"expected_result":76,"demo_url":41,"video_url":41},526,6,"Attivare le guide visive di debug: paint, animazioni e repaint","L'Inspector offre alcuni interruttori nella barra in alto che disegnano informazioni direttamente sopra l'app. Sono la versione visuale di variabili di debug che puoi anche impostare da codice.\n\n**Show Guidelines \u002F Debug Paint** (o tasto `p` nella console): disegna i bordi di ogni box, le frecce del padding e gli allineamenti. Perfetto per capire \"da dove arriva questo spazio\".\n\n**Show Baselines**: mostra le baseline tipografiche, utile per allineare testi di dimensioni diverse.\n\n**Slow Animations**: rallenta le animazioni di 5 volte per verificarne fluidità e curve.\n\n**Highlight Repaints**: colora i bordi dei layer che vengono ridisegnati; se un'area lampeggia in continuazione hai un problema di performance.\n\n**Highlight Oversized Images**: evidenzia le immagini caricate a una risoluzione molto maggiore di quella mostrata (spreco di memoria).\n\nPuoi attivare le stesse opzioni da codice, ma ricorda di **rimuoverle prima del rilascio**: sono strumenti di sviluppo.\n\nMetti tutto insieme con questo flusso di lavoro:\n\n1. Scrivi il layout → salva → **hot reload**.\n2. Qualcosa non torna? → **Select Widget Mode** sul widget incriminato.\n3. Problema di spazi\u002Fdimensioni? → **Layout Explorer** + **Debug Paint**.\n4. Lo stato è sporco o l'app parte male? → **hot restart** (`R`).\n5. Hai aggiunto un pacchetto nativo? → stop e **full restart**.","import 'package:flutter\u002Frendering.dart';\n\nvoid main() {\n  \u002F\u002F Attiva le guide di layout solo in sviluppo.\n  \u002F\u002F In alternativa usa gli interruttori dei DevTools (consigliato).\n  debugPaintSizeEnabled = true;      \u002F\u002F bordi e padding di ogni box\n  \u002F\u002F debugPaintBaselinesEnabled = true; \u002F\u002F baseline del testo\n  \u002F\u002F debugRepaintRainbowEnabled = true; \u002F\u002F colora i layer ridisegnati\n\n  runApp(const MyApp());\n}","L'app mostra bordi, frecce di padding e guide sopra ogni widget: puoi individuare visivamente margini e dimensioni inattesi.",[],1789120599402]