[{"data":1,"prerenderedAt":78},["ShallowReactive",2],{"tutorial-internazionalizzazione-i18n-in-flutter-con-flutter-localizations-e-arb":3,"comments-tutorial-internazionalizzazione-i18n-in-flutter-con-flutter-localizations-e-arb":77},{"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},13,"Internazionalizzazione (i18n) in Flutter con flutter_localizations e ARB","internazionalizzazione-i18n-in-flutter-con-flutter-localizations-e-arb","Impara a rendere multilingua la tua app Flutter usando il supporto ufficiale flutter_localizations, i file ARB e la generazione automatica delle classi di traduzione.","## Perché internazionalizzare\n\nUn'app pensata per un pubblico globale deve adattarsi alla lingua dell'utente. Flutter offre un sistema ufficiale di internazionalizzazione (i18n) basato sul pacchetto `flutter_localizations` e sui file **ARB** (Application Resource Bundle), con generazione automatica delle classi di traduzione tramite il tool `gen-l10n`.\n\nIn questo tutorial configureremo da zero il supporto multilingua per italiano e inglese, gestiremo testi con parametri e plurali, e vedremo come cambiare lingua a runtime.\n\nAl termine avrai un'app capace di tradurre dinamicamente la propria interfaccia.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F55616146-bbdb-4c2e-a2d4-0484a4da1bfe.jpg",null,"intermediate",35,"3.x","published","2026-06-18T04:30:44+00:00","Internazionalizzazione (i18n) in Flutter con ARB","Guida pratica all'i18n in Flutter: configura flutter_localizations, file ARB, plurali e cambio lingua a runtime per app multilingua.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,32,39,47,55,63,70],{"id":26,"position":19,"title":27,"body":28,"code_snippet":29,"code_language":30,"expected_result":31,"demo_url":10,"video_url":10},90,"Abilitare la generazione e aggiungere le dipendenze","Apri il file `pubspec.yaml` e aggiungi `flutter_localizations` dal SDK, `intl` per la formattazione, e abilita il flag `generate` nella sezione `flutter`. Questo flag attiva il tool ufficiale `gen-l10n` che genererà automaticamente le classi a partire dai file ARB.","dependencies:\n  flutter:\n    sdk: flutter\n  flutter_localizations:\n    sdk: flutter\n  intl: any\n\nflutter:\n  generate: true\n  uses-material-design: true","yaml","Eseguendo `flutter pub get` le dipendenze vengono scaricate senza errori.",{"id":33,"position":34,"title":35,"body":36,"code_snippet":37,"code_language":30,"expected_result":38,"demo_url":10,"video_url":10},91,2,"Configurare l10n.yaml","Crea nella root del progetto un file chiamato `l10n.yaml`. Questo file dice a `gen-l10n` dove trovare i file ARB, quale usare come template e come nominare la classe generata.","arb-dir: lib\u002Fl10n\ntemplate-arb-file: app_en.arb\noutput-localization-file: app_localizations.dart\noutput-class: AppLocalizations","Il file di configurazione è pronto per essere letto durante la build.",{"id":40,"position":41,"title":42,"body":43,"code_snippet":44,"code_language":45,"expected_result":46,"demo_url":10,"video_url":10},92,3,"Creare i file ARB di traduzione","Crea la cartella `lib\u002Fl10n` e all'interno due file: `app_en.arb` (template, inglese) e `app_it.arb` (italiano). Nei file ARB ogni chiave corrisponde a un metodo generato. I metadati con prefisso `@` descrivono i placeholder. Includiamo un saluto semplice, uno con parametro e un plurale.","\u002F\u002F app_en.arb\n{\n  \"appTitle\": \"My App\",\n  \"greeting\": \"Hello!\",\n  \"welcomeUser\": \"Welcome, {name}\",\n  \"@welcomeUser\": {\n    \"placeholders\": { \"name\": { \"type\": \"String\" } }\n  },\n  \"messageCount\": \"{count, plural, =0{No messages} =1{1 message} other{{count} messages}}\",\n  \"@messageCount\": {\n    \"placeholders\": { \"count\": { \"type\": \"int\" } }\n  }\n}\n\n\u002F\u002F app_it.arb\n{\n  \"appTitle\": \"La mia App\",\n  \"greeting\": \"Ciao!\",\n  \"welcomeUser\": \"Benvenuto, {name}\",\n  \"messageCount\": \"{count, plural, =0{Nessun messaggio} =1{1 messaggio} other{{count} messaggi}}\"\n}","json","I due file ARB sono presenti in lib\u002Fl10n con le stesse chiavi.",{"id":48,"position":49,"title":50,"body":51,"code_snippet":52,"code_language":53,"expected_result":54,"demo_url":10,"video_url":10},93,4,"Generare le classi di localizzazione","Esegui un comando di build o `flutter gen-l10n`. Flutter creerà automaticamente la classe `AppLocalizations` (di solito in `.dart_tool\u002Fflutter_gen\u002Fgen_l10n\u002F`). Da questo momento potrai importarla e usarla nel codice. Ricordati di rieseguire il comando ogni volta che modifichi i file ARB.","flutter gen-l10n\n# oppure semplicemente:\nflutter run","bash","Il file app_localizations.dart viene generato senza errori.",{"id":56,"position":57,"title":58,"body":59,"code_snippet":60,"code_language":61,"expected_result":62,"demo_url":10,"video_url":10},94,5,"Configurare MaterialApp con i delegate","Nel widget principale collega `AppLocalizations.localizationsDelegates` e `supportedLocales`. I delegate gestiscono il caricamento delle traduzioni e dei testi standard di Material\u002FCupertino\u002FWidgets. Usiamo una variabile di stato `_locale` per poterla cambiare a runtime.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:flutter_gen\u002Fgen_l10n\u002Fapp_localizations.dart';\n\nclass MyApp extends StatefulWidget {\n  const MyApp({super.key});\n  @override\n  State\u003CMyApp> createState() => MyAppState();\n}\n\nclass MyAppState extends State\u003CMyApp> {\n  Locale? _locale;\n\n  void setLocale(Locale locale) => setState(() => _locale = locale);\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      locale: _locale,\n      localizationsDelegates: AppLocalizations.localizationsDelegates,\n      supportedLocales: AppLocalizations.supportedLocales,\n      onGenerateTitle: (ctx) => AppLocalizations.of(ctx)!.appTitle,\n      home: const HomePage(),\n    );\n  }\n}","dart","L'app si avvia mostrando i testi nella lingua del dispositivo (it o en).",{"id":64,"position":65,"title":66,"body":67,"code_snippet":68,"code_language":61,"expected_result":69,"demo_url":10,"video_url":10},95,6,"Usare le traduzioni e il cambio lingua a runtime","Recupera l'istanza con `AppLocalizations.of(context)!` e richiama i metodi generati, passando i parametri dove richiesto. Per cambiare lingua a runtime risali allo `State` dell'app con `findAncestorStateOfType` (oppure usa un gestore di stato come Provider) e chiama `setLocale`.","class HomePage extends StatelessWidget {\n  const HomePage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    final t = AppLocalizations.of(context)!;\n    return Scaffold(\n      appBar: AppBar(title: Text(t.appTitle)),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: [\n            Text(t.greeting),\n            Text(t.welcomeUser('Marco')),\n            Text(t.messageCount(3)),\n            const SizedBox(height: 24),\n            ElevatedButton(\n              onPressed: () => MyApp.of(context)?.setLocale(const Locale('it')),\n              child: const Text('Italiano'),\n            ),\n            ElevatedButton(\n              onPressed: () => MyApp.of(context)?.setLocale(const Locale('en')),\n              child: const Text('English'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n\n\u002F\u002F Aggiungi questo helper statico dentro MyApp:\n\u002F\u002F static MyAppState? of(BuildContext context) =>\n\u002F\u002F     context.findAncestorStateOfType\u003CMyAppState>();","Toccando i pulsanti l'interfaccia cambia istantaneamente tra italiano e inglese, con plurali e parametri corretti.",{"id":71,"position":72,"title":73,"body":74,"code_snippet":75,"code_language":61,"expected_result":76,"demo_url":10,"video_url":10},96,7,"Best practice e refinement","Alcuni accorgimenti per un'app multilingua robusta:\n\n- **Persisti la lingua** scelta con `shared_preferences` per ricaricarla all'avvio.\n- **localeResolutionCallback**: usa un fallback esplicito quando la lingua del dispositivo non è supportata.\n- **Non concatenare stringhe manualmente**: usa sempre i placeholder ARB, perché l'ordine delle parole cambia tra le lingue.\n- **Formattazione**: usa `intl` (`DateFormat`, `NumberFormat`) per date e numeri localizzati.","MaterialApp(\n  localeResolutionCallback: (deviceLocale, supported) {\n    if (deviceLocale != null) {\n      for (final l in supported) {\n        if (l.languageCode == deviceLocale.languageCode) return l;\n      }\n    }\n    return const Locale('en');\n  },\n);","L'app sceglie sempre una lingua valida, anche su dispositivi con locale non previsto.",[],1781766636446]