[{"data":1,"prerenderedAt":75},["ShallowReactive",2],{"tutorial-rilevare-la-connessione-di-rete-in-flutter-con-connectivity-plus":3,"comments-tutorial-rilevare-la-connessione-di-rete-in-flutter-con-connectivity-plus":74},{"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},31,"Rilevare la connessione di rete in Flutter con connectivity_plus","rilevare-la-connessione-di-rete-in-flutter-con-connectivity-plus","Impara a monitorare lo stato della connessione a Internet in Flutter usando connectivity_plus, mostrando all'utente un banner quando la rete non è disponibile.","## Perché monitorare la connessione\n\nQuasi tutte le app moderne dipendono dalla rete: caricano dati da API, sincronizzano contenuti o autenticano gli utenti. Se il dispositivo perde la connessione, offrire un feedback chiaro migliora enormemente l'esperienza utente.\n\nIn questo tutorial useremo il pacchetto ufficiale **connectivity_plus** per rilevare i cambiamenti di stato della rete (Wi‑Fi, dati mobili, assenza di connessione) e mostreremo un banner reattivo quando l'utente va offline.\n\n> **Attenzione:** `connectivity_plus` indica se il dispositivo è collegato a una rete, **non** se ha realmente accesso a Internet. Vedremo come integrare un semplice controllo di raggiungibilità reale.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002Fdd744659-c6db-4928-8787-8ce90ab0ee34.jpg",null,"intermediate",30,"3.x","published","2026-07-07T04:30:50+00:00","Rilevare la rete in Flutter con connectivity_plus","Guida pratica per monitorare lo stato della connessione Internet in Flutter con connectivity_plus e mostrare un banner offline reattivo.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,32,40,47,54,61,68],{"id":26,"position":19,"title":27,"body":28,"code_snippet":29,"code_language":30,"expected_result":31,"demo_url":10,"video_url":10},209,"Aggiungere le dipendenze","Apri il file `pubspec.yaml` e aggiungi il pacchetto `connectivity_plus`. Per il controllo di raggiungibilità reale useremo anche `http`.\n\nDopo aver salvato, esegui il comando di installazione dal terminale.","dependencies:\n  flutter:\n    sdk: flutter\n  connectivity_plus: ^6.0.5\n  http: ^1.2.2","yaml","Il comando `flutter pub get` scarica i pacchetti senza errori.",{"id":33,"position":34,"title":35,"body":36,"code_snippet":37,"code_language":38,"expected_result":39,"demo_url":10,"video_url":10},210,2,"Creare un servizio per la connettività","Isoliamo la logica in una classe dedicata. Il metodo `checkConnection` verifica lo stato attuale, mentre `onConnectivityChanged` espone uno `Stream` che emette un valore ad ogni cambiamento di rete.\n\nNota che dalla versione 6.x, `checkConnectivity()` restituisce una `List\u003CConnectivityResult>` perché un dispositivo può avere più interfacce attive.","import 'package:connectivity_plus\u002Fconnectivity_plus.dart';\n\nclass ConnectivityService {\n  final Connectivity _connectivity = Connectivity();\n\n  \u002F\u002F Stream dei cambiamenti di stato della rete\n  Stream\u003CList\u003CConnectivityResult>> get onStatusChange =>\n      _connectivity.onConnectivityChanged;\n\n  \u002F\u002F Verifica se almeno una interfaccia di rete è attiva\n  Future\u003Cbool> get isConnected async {\n    final results = await _connectivity.checkConnectivity();\n    return _hasConnection(results);\n  }\n\n  bool _hasConnection(List\u003CConnectivityResult> results) {\n    return !results.contains(ConnectivityResult.none) && results.isNotEmpty;\n  }\n}","dart","La classe compila correttamente ed espone uno stream e un getter per lo stato della rete.",{"id":41,"position":42,"title":43,"body":44,"code_snippet":45,"code_language":38,"expected_result":46,"demo_url":10,"video_url":10},211,3,"Verificare l'accesso reale a Internet","Come detto, essere collegati a una rete non garantisce l'accesso a Internet (es. Wi‑Fi senza uscita). Aggiungiamo un metodo che tenta una richiesta HTTP leggera per confermare la raggiungibilità reale.\n\nUsiamo un timeout breve per non bloccare l'interfaccia in caso di rete lenta.","import 'package:http\u002Fhttp.dart' as http;\n\nextension RealConnectivity on ConnectivityService {\n  Future\u003Cbool> hasInternetAccess() async {\n    \u002F\u002F Prima controlla se c'è una interfaccia attiva\n    if (!await isConnected) return false;\n\n    try {\n      final response = await http\n          .head(Uri.parse('https:\u002F\u002Fclients3.google.com\u002Fgenerate_204'))\n          .timeout(const Duration(seconds: 3));\n      return response.statusCode == 204 || response.statusCode == 200;\n    } catch (_) {\n      return false;\n    }\n  }\n}","Il metodo restituisce `true` solo quando esiste una connessione realmente funzionante.",{"id":48,"position":49,"title":50,"body":51,"code_snippet":52,"code_language":38,"expected_result":53,"demo_url":10,"video_url":10},212,4,"Creare un widget banner reattivo","Costruiamo un widget che ascolta lo stream di connettività tramite `StreamBuilder` e mostra un banner rosso quando l'utente è offline. Utilizziamo `AnimatedContainer` per una transizione fluida.\n\nIl banner si posiziona in cima al contenuto grazie a una `Column`.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:connectivity_plus\u002Fconnectivity_plus.dart';\n\nclass ConnectivityBanner extends StatelessWidget {\n  final Widget child;\n  final ConnectivityService service;\n\n  const ConnectivityBanner({\n    super.key,\n    required this.child,\n    required this.service,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return StreamBuilder\u003CList\u003CConnectivityResult>>(\n      stream: service.onStatusChange,\n      builder: (context, snapshot) {\n        final offline = snapshot.hasData &&\n            (snapshot.data!.contains(ConnectivityResult.none) ||\n                snapshot.data!.isEmpty);\n        return Column(\n          children: [\n            AnimatedContainer(\n              duration: const Duration(milliseconds: 300),\n              height: offline ? 32 : 0,\n              width: double.infinity,\n              color: Colors.red.shade700,\n              alignment: Alignment.center,\n              child: offline\n                  ? const Text(\n                      'Nessuna connessione a Internet',\n                      style: TextStyle(color: Colors.white, fontSize: 13),\n                    )\n                  : null,\n            ),\n            Expanded(child: child),\n          ],\n        );\n      },\n    );\n  }\n}","Quando la rete cade, appare in alto un banner rosso animato; ritorna online lo nasconde.",{"id":55,"position":56,"title":57,"body":58,"code_snippet":59,"code_language":38,"expected_result":60,"demo_url":10,"video_url":10},213,5,"Integrare il banner nell'app","Avvolgiamo il corpo della nostra schermata con `ConnectivityBanner`. Passiamo un'istanza del servizio creato in precedenza.\n\nIn un'app reale è consigliabile fornire il servizio tramite Provider o get_it, ma per l'esempio lo istanziamo direttamente.","class HomePage extends StatelessWidget {\n  final ConnectivityService _service = ConnectivityService();\n\n  HomePage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Demo Connettività')),\n      body: ConnectivityBanner(\n        service: _service,\n        child: const Center(\n          child: Text('Contenuto principale dell\\'app'),\n        ),\n      ),\n    );\n  }\n}","L'app mostra il contenuto principale e reagisce ai cambi di connessione in tempo reale.",{"id":62,"position":63,"title":64,"body":65,"code_snippet":66,"code_language":38,"expected_result":67,"demo_url":10,"video_url":10},214,6,"Mostrare un messaggio all'avvio con controllo reale","All'avvio dell'app potremmo voler verificare subito l'accesso reale a Internet e avvisare l'utente con uno `SnackBar`. Usiamo il metodo `hasInternetAccess` creato prima all'interno di `initState`.\n\nRicorda di usare `mounted` prima di interagire con il context in un contesto asincrono.","class HomePage extends StatefulWidget {\n  const HomePage({super.key});\n\n  @override\n  State\u003CHomePage> createState() => _HomePageState();\n}\n\nclass _HomePageState extends State\u003CHomePage> {\n  final ConnectivityService _service = ConnectivityService();\n\n  @override\n  void initState() {\n    super.initState();\n    WidgetsBinding.instance.addPostFrameCallback((_) => _checkAtStartup());\n  }\n\n  Future\u003Cvoid> _checkAtStartup() async {\n    final ok = await _service.hasInternetAccess();\n    if (!ok && mounted) {\n      ScaffoldMessenger.of(context).showSnackBar(\n        const SnackBar(content: Text('Sei offline: alcune funzioni non saranno disponibili')),\n      );\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Demo Connettività')),\n      body: ConnectivityBanner(\n        service: _service,\n        child: const Center(child: Text('Contenuto principale')),\n      ),\n    );\n  }\n}","All'avvio, se non c'è accesso reale a Internet, compare uno SnackBar informativo.",{"id":69,"position":70,"title":71,"body":72,"code_snippet":10,"code_language":38,"expected_result":73,"demo_url":10,"video_url":10},215,7,"Testare su dispositivo ed emulatore","Per verificare il comportamento:\n\n- **Emulatore Android:** attiva\u002Fdisattiva la modalità aereo o usa i controlli di rete dell'emulatore.\n- **Dispositivo fisico:** disattiva il Wi‑Fi e i dati mobili.\n- **iOS Simulator:** simula lo stato offline disattivando la rete del Mac.\n\nOsserva il banner apparire e scomparire. Prova anche a collegarti a una rete Wi‑Fi senza Internet per verificare che `hasInternetAccess` restituisca correttamente `false`.\n\n### Prossimi passi\n\n- Integra il servizio con Provider o Riverpod per condividerlo in tutta l'app.\n- Metti in coda le richieste fallite per rieseguirle al ritorno online.\n- Combina il banner con un sistema di cache per un vero supporto offline-first.","Il banner e lo SnackBar reagiscono correttamente ai cambi di stato in tutti gli scenari testati.",[],1785219609332]