[{"data":1,"prerenderedAt":78},["ShallowReactive",2],{"tutorial-condividere-dati-tra-schermate-in-flutter-con-navigator-risultati-e-argomenti":3,"comments-tutorial-condividere-dati-tra-schermate-in-flutter-con-navigator-risultati-e-argomenti":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},123,"Condividere dati tra schermate in Flutter con Navigator: risultati e argomenti","condividere-dati-tra-schermate-in-flutter-con-navigator-risultati-e-argomenti","Impara a passare dati a una nuova schermata e a ricevere un risultato di ritorno con Navigator.push e Navigator.pop, usando costruttori tipizzati e async\u002Fawait.","Quando un'app cresce, le schermate devono scambiarsi informazioni: un elenco apre un dettaglio, una pagina di scelta restituisce il valore selezionato.\n\nIn questo tutorial beginner vedremo come:\n\n- passare **argomenti** a una schermata tramite il costruttore;\n- ricevere un **risultato** quando la schermata si chiude;\n- gestire il caso in cui l'utente annulla (risultato `null`).\n\nServe solo un progetto Flutter vuoto creato con `flutter create`.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F52fb183e-3f43-46a3-807b-a4b789359df1.jpg","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1691343865362-7958c6fa6b6e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w5NzA2NTJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3OTE4NjU5Mjd8&ixlib=rb-4.1.0&q=80&w=1080",{"name":12,"author_url":13,"photo_url":14},"serjan midili","https:\u002F\u002Funsplash.com\u002F@s_midili","https:\u002F\u002Funsplash.com\u002Fphotos\u002Ftwo-cars-parked-next-to-each-other-in-a-parking-lot--vwSsm0DTtE","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=WScZbk_htk8",{"youtube_id":17,"duration_seconds":18,"published_at":19},"WScZbk_htk8",108,"2026-10-13T12:16:42+00:00","beginner",30,"3.x","published","2026-10-13T04:32:08+00:00","Passare dati tra schermate Flutter con Navigator","Guida beginner per passare argomenti e ricevere risultati tra schermate Flutter con Navigator.push, Navigator.pop e async\u002Fawait.",{"id":28,"name":29,"slug":30},1,"Guide","guide",{"id":28,"name":32},"Flutter Bot",[34,42,49,56,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},822,"Preparare l'app e la schermata iniziale","Sostituisci il contenuto di `lib\u002Fmain.dart` con una `MaterialApp` e una `HomePage` che mostra il nome di un profilo utente e un pulsante per modificarlo.\n\nPer ora il pulsante non fa nulla: lo collegheremo nei passi successivi.","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: 'Navigator 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  String _nome = 'Mario Rossi';\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Profilo')),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: [\n            Text(_nome, style: Theme.of(context).textTheme.headlineSmall),\n            const SizedBox(height: 16),\n            FilledButton(\n              onPressed: () {},\n              child: const Text('Modifica nome'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}","dart","L'app si avvia e mostra il nome 'Mario Rossi' con un pulsante ancora inattivo.",null,{"id":43,"position":44,"title":45,"body":46,"code_snippet":47,"code_language":39,"expected_result":48,"demo_url":41,"video_url":41},823,2,"Creare la seconda schermata che riceve un argomento","La seconda schermata riceve il nome attuale tramite il **costruttore**: è il modo più semplice e sicuro (tipizzato) per passare dati con Navigator.\n\nCrea il file `lib\u002Fedit_page.dart` con un `TextField` precompilato.","import 'package:flutter\u002Fmaterial.dart';\n\nclass EditPage extends StatefulWidget {\n  const EditPage({super.key, required this.nomeIniziale});\n\n  final String nomeIniziale;\n\n  @override\n  State\u003CEditPage> createState() => _EditPageState();\n}\n\nclass _EditPageState extends State\u003CEditPage> {\n  late final TextEditingController _controller =\n      TextEditingController(text: widget.nomeIniziale);\n\n  @override\n  void dispose() {\n    _controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Modifica nome')),\n      body: Padding(\n        padding: const EdgeInsets.all(16),\n        child: Column(\n          children: [\n            TextField(\n              controller: _controller,\n              autofocus: true,\n              decoration: const InputDecoration(\n                labelText: 'Nome',\n                border: OutlineInputBorder(),\n              ),\n            ),\n            const SizedBox(height: 16),\n            FilledButton(\n              onPressed: () {},\n              child: const Text('Salva'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}","Il file compila senza errori: la schermata mostra un campo di testo precompilato.",{"id":50,"position":51,"title":52,"body":53,"code_snippet":54,"code_language":39,"expected_result":55,"demo_url":41,"video_url":41},824,3,"Aprire la schermata con Navigator.push","Da `HomePage` apriamo `EditPage` passando il nome attuale. `MaterialPageRoute` è tipizzato con `\u003CString>` perché ci aspettiamo una stringa come risultato.\n\nRicorda di importare `edit_page.dart` in `main.dart`.","import 'edit_page.dart';\n\n\u002F\u002F dentro _HomePageState\nFuture\u003Cvoid> _apriModifica() async {\n  await Navigator.push\u003CString>(\n    context,\n    MaterialPageRoute\u003CString>(\n      builder: (context) => EditPage(nomeIniziale: _nome),\n    ),\n  );\n}\n\n\u002F\u002F collega il pulsante:\n\u002F\u002F FilledButton(onPressed: _apriModifica, child: const Text('Modifica nome')),","Toccando il pulsante si apre la seconda schermata con il nome già inserito nel campo.",{"id":57,"position":58,"title":59,"body":60,"code_snippet":61,"code_language":39,"expected_result":62,"demo_url":41,"video_url":41},825,4,"Restituire un risultato con Navigator.pop","Per restituire un valore alla schermata precedente basta passarlo come secondo argomento di `Navigator.pop`.\n\nAggiungiamo anche un controllo: se il campo è vuoto non chiudiamo la pagina.","FilledButton(\n  onPressed: () {\n    final testo = _controller.text.trim();\n    if (testo.isEmpty) {\n      ScaffoldMessenger.of(context).showSnackBar(\n        const SnackBar(content: Text('Il nome non può essere vuoto')),\n      );\n      return;\n    }\n    Navigator.pop(context, testo);\n  },\n  child: const Text('Salva'),\n),","Premendo 'Salva' la schermata si chiude; con il campo vuoto appare invece una SnackBar.",{"id":64,"position":65,"title":66,"body":67,"code_snippet":68,"code_language":39,"expected_result":69,"demo_url":41,"video_url":41},826,5,"Ricevere il risultato con await e aggiornare la UI","`Navigator.push` restituisce un `Future` che si completa quando la rotta viene chiusa. Il valore può essere `null` se l'utente torna indietro con la freccia o con il gesto di sistema: va sempre gestito.\n\nUsa anche `context.mounted` prima di toccare il context dopo un `await`.","Future\u003Cvoid> _apriModifica() async {\n  final risultato = await Navigator.push\u003CString>(\n    context,\n    MaterialPageRoute\u003CString>(\n      builder: (context) => EditPage(nomeIniziale: _nome),\n    ),\n  );\n\n  if (!context.mounted) return;\n\n  if (risultato == null) {\n    ScaffoldMessenger.of(context).showSnackBar(\n      const SnackBar(content: Text('Modifica annullata')),\n    );\n    return;\n  }\n\n  setState(() => _nome = risultato);\n}","Salvando, il nome in home si aggiorna; tornando indietro senza salvare compare 'Modifica annullata'.",{"id":71,"position":72,"title":73,"body":74,"code_snippet":75,"code_language":39,"expected_result":76,"demo_url":41,"video_url":41},827,6,"Passare oggetti complessi, non solo stringhe","Lo stesso schema funziona con qualunque tipo: definisci una semplice classe e usala come parametro del costruttore e come tipo di ritorno.\n\nÈ la base per un flusso lista → dettaglio → modifica.","class Profilo {\n  const Profilo({required this.nome, required this.eta});\n  final String nome;\n  final int eta;\n}\n\n\u002F\u002F apertura\nfinal nuovo = await Navigator.push\u003CProfilo>(\n  context,\n  MaterialPageRoute\u003CProfilo>(\n    builder: (_) => EditProfiloPage(profilo: profiloAttuale),\n  ),\n);\n\n\u002F\u002F chiusura nella seconda schermata\n\u002F\u002F Navigator.pop(context, Profilo(nome: 'Anna', eta: 30));","Puoi scambiare interi oggetti tra schermate mantenendo il type-safety del compilatore.",[],1792316904077]