[{"data":1,"prerenderedAt":68},["ShallowReactive",2],{"tutorial-persistenza-dei-dati-locali-in-flutter-con-shared-preferences":3,"comments-tutorial-persistenza-dei-dati-locali-in-flutter-con-shared-preferences":67},{"id":4,"title":5,"slug":6,"excerpt":7,"intro":8,"cover_image":9,"video_url":10,"difficulty":11,"estimated_minutes":12,"flutter_version":13,"status":14,"published_at":15,"meta_title":16,"meta_description":17,"category":18,"author":22,"steps":24},4,"Persistenza dei dati locali in Flutter con shared_preferences","persistenza-dei-dati-locali-in-flutter-con-shared-preferences","Impara a salvare e leggere dati semplici come impostazioni utente e preferenze direttamente sul dispositivo usando il pacchetto shared_preferences.","In molte app è necessario memorizzare piccole quantità di dati in modo persistente: il tema scelto dall'utente, un flag che indica se l'onboarding è già stato completato, o l'ultimo username inserito.\n\nIl pacchetto **shared_preferences** è la soluzione ideale per questi casi: salva coppie chiave-valore in modo persistente sfruttando i meccanismi nativi di ogni piattaforma (NSUserDefaults su iOS, SharedPreferences su Android, ecc.).\n\nIn questo tutorial costruiremo una piccola app che salva e ripristina le preferenze dell'utente, e vedremo come incapsulare la logica in un servizio riutilizzabile.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002Febdd9fbb-dbc5-4a15-9e05-eb1ce9cd75d6.jpg",null,"beginner",25,"3.x","published","2026-06-09T06:25:53+00:00","Flutter shared_preferences: salvare dati locali","Guida pratica per salvare e leggere dati locali in Flutter con shared_preferences: setup, lettura, scrittura e un servizio riutilizzabile.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,32,40,47,53,60],{"id":26,"position":19,"title":27,"body":28,"code_snippet":29,"code_language":30,"expected_result":31,"demo_url":10,"video_url":10},32,"Aggiungere la dipendenza","Per prima cosa aggiungiamo il pacchetto `shared_preferences` al nostro progetto. Puoi usare il comando da terminale oppure modificare direttamente il file `pubspec.yaml`.\n\nUsa il comando seguente nella cartella del progetto:","flutter pub add shared_preferences","bash","Nel file pubspec.yaml comparirà la dipendenza shared_preferences sotto la sezione dependencies e le dipendenze verranno scaricate.",{"id":33,"position":34,"title":35,"body":36,"code_snippet":37,"code_language":38,"expected_result":39,"demo_url":10,"video_url":10},33,2,"Creare un servizio per le preferenze","Per mantenere il codice ordinato, incapsuliamo la logica di lettura e scrittura in una classe dedicata. In questo modo evitiamo di sparpagliare le chiamate a `SharedPreferences` in tutta l'app.\n\nCreiamo il file `lib\u002Fservices\u002Fpreferences_service.dart` con metodi per salvare e leggere il nome utente e una flag booleana per il tema scuro.","import 'package:shared_preferences\u002Fshared_preferences.dart';\n\nclass PreferencesService {\n  static const _keyUsername = 'username';\n  static const _keyDarkMode = 'dark_mode';\n\n  Future\u003Cvoid> saveUsername(String username) async {\n    final prefs = await SharedPreferences.getInstance();\n    await prefs.setString(_keyUsername, username);\n  }\n\n  Future\u003CString?> getUsername() async {\n    final prefs = await SharedPreferences.getInstance();\n    return prefs.getString(_keyUsername);\n  }\n\n  Future\u003Cvoid> setDarkMode(bool value) async {\n    final prefs = await SharedPreferences.getInstance();\n    await prefs.setBool(_keyDarkMode, value);\n  }\n\n  Future\u003Cbool> isDarkMode() async {\n    final prefs = await SharedPreferences.getInstance();\n    return prefs.getBool(_keyDarkMode) ?? false;\n  }\n}","dart","Avrai una classe PreferencesService riutilizzabile con metodi asincroni per gestire username e tema.",{"id":41,"position":42,"title":43,"body":44,"code_snippet":45,"code_language":38,"expected_result":46,"demo_url":10,"video_url":10},34,3,"Costruire l'interfaccia utente","Creiamo una semplice schermata con un `TextField` per inserire lo username e uno `Switch` per attivare il tema scuro. Usiamo uno `StatefulWidget` per gestire lo stato locale dei controlli.","import 'package:flutter\u002Fmaterial.dart';\nimport 'services\u002Fpreferences_service.dart';\n\nclass SettingsPage extends StatefulWidget {\n  const SettingsPage({super.key});\n\n  @override\n  State\u003CSettingsPage> createState() => _SettingsPageState();\n}\n\nclass _SettingsPageState extends State\u003CSettingsPage> {\n  final _service = PreferencesService();\n  final _controller = TextEditingController();\n  bool _darkMode = false;\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Impostazioni')),\n      body: Padding(\n        padding: const EdgeInsets.all(16),\n        child: Column(\n          children: [\n            TextField(\n              controller: _controller,\n              decoration: const InputDecoration(labelText: 'Username'),\n            ),\n            SwitchListTile(\n              title: const Text('Tema scuro'),\n              value: _darkMode,\n              onChanged: (v) => setState(() => _darkMode = v),\n            ),\n            const SizedBox(height: 16),\n            ElevatedButton(\n              onPressed: _save,\n              child: const Text('Salva'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n\n  Future\u003Cvoid> _save() async {}\n}","Una schermata Impostazioni con campo testo, switch e pulsante Salva, ancora non collegati alla persistenza.",{"id":48,"position":4,"title":49,"body":50,"code_snippet":51,"code_language":38,"expected_result":52,"demo_url":10,"video_url":10},35,"Salvare i dati al tocco del pulsante","Implementiamo il metodo `_save` per scrivere i valori inseriti dall'utente tramite il nostro `PreferencesService`. Mostriamo anche uno `SnackBar` di conferma.","Future\u003Cvoid> _save() async {\n  await _service.saveUsername(_controller.text);\n  await _service.setDarkMode(_darkMode);\n\n  if (!mounted) return;\n  ScaffoldMessenger.of(context).showSnackBar(\n    const SnackBar(content: Text('Preferenze salvate!')),\n  );\n}","Premendo Salva i dati vengono persistiti sul dispositivo e appare un messaggio di conferma.",{"id":54,"position":55,"title":56,"body":57,"code_snippet":58,"code_language":38,"expected_result":59,"demo_url":10,"video_url":10},36,5,"Caricare i dati all'avvio","Per ripristinare le preferenze salvate quando l'utente riapre la schermata, leggiamo i valori in `initState`. Poiché le chiamate sono asincrone, usiamo un metodo separato e aggiorniamo lo stato con `setState`.","@override\nvoid initState() {\n  super.initState();\n  _loadPreferences();\n}\n\nFuture\u003Cvoid> _loadPreferences() async {\n  final username = await _service.getUsername();\n  final darkMode = await _service.isDarkMode();\n\n  if (!mounted) return;\n  setState(() {\n    _controller.text = username ?? '';\n    _darkMode = darkMode;\n  });\n}","Riaprendo l'app o la schermata, i valori precedentemente salvati appaiono già compilati nei controlli.",{"id":61,"position":62,"title":63,"body":64,"code_snippet":65,"code_language":38,"expected_result":66,"demo_url":10,"video_url":10},37,6,"Aggiungere un metodo per cancellare i dati","Infine è utile poter ripristinare le impostazioni di default. Aggiungiamo al servizio un metodo per rimuovere una singola chiave o azzerare tutte le preferenze, e colleghiamolo a un pulsante.\n\n> **Nota:** usa `remove` per cancellare una chiave specifica e `clear` per eliminare tutto. Attenzione: `clear` rimuove anche i dati salvati da altre parti dell'app.","\u002F\u002F In PreferencesService\nFuture\u003Cvoid> clearAll() async {\n  final prefs = await SharedPreferences.getInstance();\n  await prefs.clear();\n}\n\n\u002F\u002F Nella UI, ad esempio in un pulsante:\nElevatedButton(\n  onPressed: () async {\n    await _service.clearAll();\n    if (!mounted) return;\n    setState(() {\n      _controller.clear();\n      _darkMode = false;\n    });\n  },\n  child: const Text('Ripristina default'),\n)","Premendo il pulsante di ripristino, tutte le preferenze vengono cancellate e i controlli tornano ai valori di default.",[],1781247857896]