Flattern - Internationalisierung

Heutzutage werden mobile Anwendungen von Kunden aus verschiedenen Ländern verwendet. Daher müssen Anwendungen den Inhalt in verschiedenen Sprachen anzeigen. Das Aktivieren einer Anwendung in mehreren Sprachen wird als Internationalisierung der Anwendung bezeichnet.

Damit eine Anwendung in verschiedenen Sprachen funktioniert, sollte sie zuerst das aktuelle Gebietsschema des Systems finden, auf dem die Anwendung ausgeführt wird, und dann den Inhalt in diesem bestimmten Gebietsschema anzeigen. Dieser Vorgang wird als Lokalisierung bezeichnet.

Das Flutter-Framework bietet drei Basisklassen für die Lokalisierung und umfangreiche Dienstprogrammklassen, die von Basisklassen zur Lokalisierung einer Anwendung abgeleitet wurden.

Die Basisklassen sind wie folgt:

  • Gebietsschema - Gebietsschema ist eine Klasse, mit der die Sprache des Benutzers identifiziert wird. Zum Beispiel identifiziert en-us das amerikanische Englisch und es kann als erstellt werden.

Locale en_locale = Locale('en', 'US')

Hier ist das erste Argument der Sprachcode und das zweite Argument der Ländercode. Ein weiteres Beispiel für die Erstellung eines spanischen (es-ar) Gebietsschemas für Argentinien ist das Folgende:

Locale es_locale = Locale('es', 'AR')
  • Lokalisierungen - Lokalisierungen sind ein generisches Widget, mit dem das Gebietsschema und die lokalisierten Ressourcen des untergeordneten Elements festgelegt werden.

class CustomLocalizations { 
   CustomLocalizations(this.locale); 
   final Locale locale; 
   static CustomLocalizations of(BuildContext context) { 
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   } 
   static Map<String, Map<String, String>> _resources = {
      'en': {
         'title': 'Demo', 
         'message': 'Hello World' 
      }, 
      'es': {
         'title': 'Manifestación', 
         'message': 'Hola Mundo', 
      }, 
   }; 
   String get title { 
      return _resources[locale.languageCode]['title']; 
   }
   String get message { 
      return _resources[locale.languageCode]['message']; 
   } 
}
  • Hier ist CustomLocalizations eine neue benutzerdefinierte Klasse, die speziell erstellt wurde, um bestimmte lokalisierte Inhalte (Titel und Nachricht) für das Widget abzurufen. Die Methode verwendet die Localizations-Klasse, um eine neue CustomLocalizations-Klasse zurückzugeben.

  • LocalizationsDelegate <T> - LocalizationsDelegate <T> ist eine Factory-Klasse, über die das Localizations-Widget geladen wird. Es gibt drei überfahrbare Methoden -

    • isSupported - Akzeptiert ein Gebietsschema und gibt zurück, ob das angegebene Gebietsschema unterstützt wird oder nicht.

@override 
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);

      Hier arbeitet der Delegat nur für das Gebietsschema en und es.

    • load - Akzeptiert ein Gebietsschema und beginnt mit dem Laden der Ressourcen für das angegebene Gebietsschema.

@override 
Future<CustomLocalizations> load(Locale locale) { 
   return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale)); 
}

      Hier gibt die Lademethode CustomLocalizations zurück. Die zurückgegebenen CustomLocalizations können verwendet werden, um Titel- und Nachrichtenwerte in Englisch und Spanisch abzurufen

    • shouldReload - Gibt an, ob das Neuladen von CustomLocalizations erforderlich ist, wenn das Widget "Lokalisierungen" neu erstellt wird.

@override 
bool shouldReload(CustomLocalizationsDelegate old) => false;
  • Der vollständige Code von CustomLocalizationDelegate lautet wie folgt:

class CustomLocalizationsDelegate extends 
LocalizationsDelegate<CustomLocalizations> { 
   const CustomLocalizationsDelegate(); 
   @override 
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale));
   } 
   @override bool shouldReload(CustomLocalizationsDelegate old) => false; 
}

Im Allgemeinen basieren Flutter-Anwendungen auf zwei Widgets auf Stammebene, MaterialApp oder WidgetsApp. Flutter bietet eine vorgefertigte Lokalisierung für beide Widgets und es handelt sich um MaterialLocalizations und WidgetsLocaliations. Darüber hinaus stellt Flutter Delegaten zum Laden von MaterialLocalizations und WidgetsLocaliations zur Verfügung. Diese sind GlobalMaterialLocalizations.delegate bzw. GlobalWidgetsLocalizations.delegate.

Lassen Sie uns eine einfache internationalisierungsfähige Anwendung erstellen, um das Konzept zu testen und zu verstehen.

  • Erstellen Sie eine neue Flatteranwendung, flutter_localization_app.

  • Flutter unterstützt die Internationalisierung mit dem exklusiven Flatterpaket flutter_localizations. Die Idee ist, den lokalisierten Inhalt vom Haupt-SDK zu trennen. Öffnen Sie die Datei pubspec.yaml und fügen Sie den folgenden Code hinzu, um das Internationalisierungspaket zu aktivieren.

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations:
      sdk: flutter
  • Android Studio zeigt die folgende Warnung an, dass die Datei pubspec.yaml aktualisiert wird.

  • Klicken Sie auf die Option Abhängigkeiten abrufen. Android Studio holt das Paket aus dem Internet und konfiguriert es ordnungsgemäß für die Anwendung.

  • Importieren Sie das Paket flutter_localizations wie folgt in den main.dart -

import 'package:flutter_localizations/flutter_localizations.dart'; 
import 'package:flutter/foundation.dart' show SynchronousFuture;
  • Hier besteht der Zweck von SynchronousFuture darin, die benutzerdefinierten Lokalisierungen synchron zu laden.

  • Erstellen Sie eine benutzerdefinierte Lokalisierung und den entsprechenden Delegaten wie unten angegeben.

class CustomLocalizations { 
   CustomLocalizations(this.locale); 
   final Locale locale; 
   static CustomLocalizations of(BuildContext context) {
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   }
   static Map<String, Map<String, String>> _resources = {
      'en': {
         'title': 'Demo', 
         'message': 'Hello World' 
      }, 
      'es': { 
         'title': 'Manifestación', 
         'message': 'Hola Mundo', 
      }, 
   }; 
   String get title { 
      return _resources[locale.languageCode]['title']; 
   } 
   String get message { 
      return _resources[locale.languageCode]['message']; 
   } 
}
class CustomLocalizationsDelegate extends
LocalizationsDelegate<CustomLocalizations> {
   const CustomLocalizationsDelegate();
   
   @override 
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); 
   
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale)); 
   } 
   @override bool shouldReload(CustomLocalizationsDelegate old) => false; 
}
  • Hier wird CustomLocalizations erstellt, um die Lokalisierung von Titel und Nachricht in der Anwendung zu unterstützen, und CustomLocalizationsDelegate wird zum Laden von CustomLocalizations verwendet.

  • Fügen Sie Delegaten für MaterialApp, WidgetsApp und CustomLocalization hinzu, indem Sie die MaterialApp-Eigenschaften, localizationsDelegates und supportLocales wie unten angegeben verwenden.

localizationsDelegates: [
   const CustomLocalizationsDelegate(),   
   GlobalMaterialLocalizations.delegate, 
   GlobalWidgetsLocalizations.delegate, 
], 
supportedLocales: [
   const Locale('en', ''),
   const Locale('es', ''), 
],
  • Verwenden Sie die CustomLocalizations-Methode, um den lokalisierten Wert von Titel und Nachricht abzurufen und an der entsprechenden Stelle wie unten angegeben zu verwenden.

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(CustomLocalizations .of(context) .title), ), 
         body: Center(
            child: Column(
               mainAxisAlignment: MainAxisAlignment.center, 
               children: <Widget>[ 
                  Text( CustomLocalizations .of(context) .message, ), 
               ], 
            ), 
         ),
      );
   }
}
  • Hier haben wir die MyHomePage-Klasse aus Gründen der Einfachheit von StatefulWidget in StatelessWidget geändert und die CustomLocalizations verwendet, um Titel und Nachricht abzurufen.

  • Kompilieren Sie die Anwendung und führen Sie sie aus. Die Anwendung zeigt ihren Inhalt in englischer Sprache.

  • Schließen Sie die Anwendung. Gehe zuSettings → System → Languages and Input → Languages*.

  • Klicken Sie auf Sprachoption hinzufügen und wählen Sie Spanisch. Dadurch wird die spanische Sprache installiert und als eine der Optionen aufgeführt.

  • Wählen Sie Spanisch und verschieben Sie es über Englisch. Dies wird als Spanisch als Muttersprache festgelegt und alles wird in spanischen Text geändert.

  • Starten Sie nun die Internationalisierungsanwendung neu und Sie sehen den Titel und die Nachricht in spanischer Sprache.

  • Wir können die Sprache auf Englisch zurücksetzen, indem wir die englische Option über die spanische Option in der Einstellung verschieben.

  • Das Ergebnis der Bewerbung (auf Spanisch) ist im folgenden Screenshot dargestellt -

Verwenden des intl-Pakets

Flutter bietet ein intl-Paket, um die Entwicklung lokalisierter mobiler Anwendungen weiter zu vereinfachen. Das intl-Paket bietet spezielle Methoden und Tools zum halbautomatischen Generieren sprachspezifischer Nachrichten.

Lassen Sie uns mithilfe des intl-Pakets eine neue lokalisierte Anwendung erstellen und das Konzept verstehen.

  • Erstellen Sie eine neue Flatteranwendung, flutter_intl_app.

  • Öffnen Sie pubspec.yaml und fügen Sie die Paketdetails hinzu.

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations: 
      sdk: flutter 
   intl: ^0.15.7 
   intl_translation: ^0.17.3
  • Android Studio zeigt die unten gezeigte Warnung an und informiert Sie darüber, dass die Datei pubspec.yaml aktualisiert wird.

  • Klicken Sie auf die Option Abhängigkeiten abrufen. Android Studio holt das Paket aus dem Internet und konfiguriert es ordnungsgemäß für die Anwendung.

  • Kopieren Sie den main.dart aus dem vorherigen Beispiel flutter_internationalization_app.

  • Importieren Sie das intl-Paket wie unten gezeigt -

import 'package:intl/intl.dart';
  • Aktualisieren Sie die CustomLocalization-Klasse wie im folgenden Code gezeigt -

class CustomLocalizations { 
   static Future<CustomLocalizations> load(Locale locale) {
      final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); 
      final String localeName = Intl.canonicalizedLocale(name); 
      
      return initializeMessages(localeName).then((_) {
         Intl.defaultLocale = localeName; 
         return CustomLocalizations(); 
      }); 
   } 
   static CustomLocalizations of(BuildContext context) { 
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   } 
   String get title {
      return Intl.message( 
         'Demo', 
         name: 'title', 
         desc: 'Title for the Demo application', 
      ); 
   }
   String get message{
      return Intl.message(
         'Hello World', 
         name: 'message', 
         desc: 'Message for the Demo application', 
      ); 
   }
}
class CustomLocalizationsDelegate extends 
LocalizationsDelegate<CustomLocalizations> {
   const CustomLocalizationsDelegate();
   
   @override
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); 
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return CustomLocalizations.load(locale); 
   } 
   @override 
   bool shouldReload(CustomLocalizationsDelegate old) => false; 
}
  • Hier haben wir drei Methoden aus dem intl-Paket anstelle von benutzerdefinierten Methoden verwendet. Ansonsten sind die Konzepte gleich.

    • Intl.canonicalizedLocale - Wird verwendet, um den korrekten Namen des Gebietsschemas abzurufen.

    • Intl.defaultLocale - Dient zum Festlegen des aktuellen Gebietsschemas

    • Intl.message - Dient zum Definieren neuer Nachrichten.

  • importieren l10n/messages_all.dartDatei. Wir werden diese Datei in Kürze generieren

import 'l10n/messages_all.dart';
  • Erstellen Sie nun einen Ordner, lib / l10n

  • Öffnen Sie eine Eingabeaufforderung, wechseln Sie zum Anwendungsstammverzeichnis (wo pubspec.yaml verfügbar ist) und führen Sie den folgenden Befehl aus:

flutter packages pub run intl_translation:extract_to_arb --output-
   dir=lib/l10n lib/main.dart
  • Hier generiert der Befehl die Datei intl_message.arb, eine Vorlage zum Erstellen einer Nachricht in einem anderen Gebietsschema. Der Inhalt der Datei ist wie folgt:

{
   "@@last_modified": "2019-04-19T02:04:09.627551", 
   "title": "Demo", 
   "@title": {
      "description": "Title for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   }, 
   "message": "Hello World", 
   "@message": {
      "description": "Message for the Demo 
      application", 
      "type": "text", 
      "placeholders": {} 
   }
}
  • Kopieren Sie intl_message.arb und erstellen Sie die neue Datei intl_en.arb.

  • Kopieren Sie intl_message.arb und erstellen Sie die neue Datei intl_es.arb und ändern Sie den Inhalt in die spanische Sprache, wie unten gezeigt -

{
   "@@last_modified": "2019-04-19T02:04:09.627551",  
   "title": "Manifestación", 
   "@title": {
      "description": "Title for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   },
   "message": "Hola Mundo",
   "@message": {
      "description": "Message for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   } 
}
  • Führen Sie nun den folgenden Befehl aus, um die endgültige Nachrichtendatei messages_all.dart zu erstellen.

flutter packages pub run intl_translation:generate_from_arb 
--output-dir=lib\l10n --no-use-deferred-loading 
lib\main.dart lib\l10n\intl_en.arb lib\l10n\intl_es.arb
  • Kompilieren Sie die Anwendung und führen Sie sie aus. Es funktioniert ähnlich wie in der obigen Anwendung flutter_localization_app.