Flutter lernen ist sehr einfach. Und so schön und leicht Flutter auch zu benutzen ist, so habe ich doch verzweifelt nach einer einfachen Lösung für ein wichtiges Problem gesucht: Internationalization. Das Framework hat leider noch keine eigene Art und Weise, wie das zu lösen ist, und überlässt es dem Nutzer, mit der Dart Variante klarzukommen, welche… ein wenig kompliziert zu verstehen ist.
Nach langer Suche habe ich jedoch einen schnellen und einfachen Weg gefunden eine Flutter-App zu übersetzen.
Voraussetzung
Für diesen Weg verwende ich ein Plugin für VisualStudioCode. Dementsprechend brauchst du diese Entwicklungsumgebung für dieses Tutorial. Allerdings gibt es auch ein ähnliches Plugin für Android Studio.
Plugin installieren
Zuallererst installierst du folgendes Plugin.
Alternativ kannst du in VSCode auch einfach unter dem Extensions-Reiter links in der Leiste nach vscode-flutter-i18n-json suchen:
Initialisieren
Nun rufst du die sogenannte Workbench auf, um Code-Befehle auszuführen. Standardmäßig ist das Ctrl/Meta/Cmd+Shift+P oder einfach nur F1.
Wichtig ist hier, dass ganz am Anfang das > steht, da VSCode sonst versucht eine Datei mit dem Namen zu öffnen, anstatt einen Befehl auszuführen.
Dort gibst du Flutter I18n Json: Initialize ein und danach den Regionscode für die Sprache, welche standardmäßig verwendet werden soll. Alternativ kannst du auch nichts eingeben und enter drücken, wenn du en-US als Standard haben möchtest.
Das GIF des Pluginerstellers zeigt sehr gut wie das abläuft:
Region hinzufügen
Internationalization macht wenig Sinn, wenn man nur eine Sprache/Region unterstützt. Also fügen wir eine weitere Region hinzu. Dafür hat das Plugin auch einen Befehl, welcher Flutter I18n Json: Add locale heißt. Nach Eingabe dessen musst du wieder einen Regionscode angeben.
Hinweis zur Verwendung unter iOS
Für die iOS Entwicklung muss momentan die info.plist, die unter /ios/runner/info.plist zu finden ist, bearbeitet und der folgende key mit einem array, das alle unterstützten Sprachen enthält, hinzugefügt werden:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>de</string>
</array>
Übersetzungen bearbeiten
Die Übersetzungsdateien für jede Sprache sollten nun im i18n Ordner liegen:
In diesen Dateien kannst du deine Übersetzungen mit Schlüssel-Wert Paaren hinzufügen. Dabei ist der erste String die Variable, mit der du die Übersetzung abrufst und der zweite String, was in der Stelle ausgegeben wird. Zudem kannst du mit geschwungenen Klammern ( {} ) Werte in den ausgegebenen Text einfügen, die du später erst kennst, z.B.: der Name eines Nutzers.
{
"greetTo": "Hallo {name}",
"test": "Dies ist eine Testnachricht",
"title": "Internationalization Beispiel"
}
Ein wichtiger Schritt bevor die Änderungen auch wirklich übernommen werden: nach dem Speichern musst du die Code Toolbox öffnen und Flutter I18n Json: Update ausführen.
Übersetzungen abrufen
Um die Übersetzungen zu verwenden, musst du in die pubspec.yaml gehen und das flutter_localizations package hinzufügen:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
Das wird benötigt, um manche Standard Widgets automatisch zu übersetzen und ohne bekommt man in manchen Fällen Fehler. Danach nur noch in die main.dart gehen und folgende Dinge hinzufügen:
import 'package:flutter_localizations/flutter_localizations.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final i18n = I18n.delegate;
return MaterialApp(
localizationsDelegates: [
i18n,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: i18n.supportedLocales,
localeResolutionCallback: i18n.resolution(
fallback: new Locale("en", "US"),
),
Wobei du bei fallback deine standard Region angibst.
Danach kannst du überall in deiner App die generierte I18n Klasse importieren und die Übersetzung abrufen. Wenn du Variablen in deiner Übersetzung hast, kannst du in Klammern die einzusetzenden Werte angeben.
import 'package:internationalization/generated/i18n.dart';
return Scaffold(
appBar: AppBar(
title: Text(I18n.of(context).title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
I18n.of(context).test,
),
Text(
I18n.of(context).greetTo('Tobias'),
style: Theme.of(context).textTheme.display1,
),
],
),
),
);
Beispiel
Zusammenfassung
Einrichten
VS Code Plugin installieren
Flutter I18n Json: Initialize ausführen
Gewünschte Regionen mit Flutter I18n Json: Add locale hinzufügen
Sprachkürzel in der Konfigurationsdatei vom iOS Runner angeben
flutter_localizations package hinzufügen und delegates in der main.dart angeben
Übersetzungen erweitern und verwenden
Die jeweiligen .json Dateien im i18n Ordner öffnen und Schlüssel-Wert Paare hinzufügen
Speichern und Flutter I18n Json: Update ausführen
Die generierte I18n.dart importieren und die Übersetzung mit I18n.of(context).übersetzungsschlüssel oder I18n.of(context).übersetzungsschlüssel("eingesetzter wert") abrufen.
Das Plugin macht das Ganze also zu einem viel schmerzloseren Prozess, als das manuelle Einpflegen der ganzen Übersetzungen und Erweitern der Klasse. Hoffentlich legt Google aber mit einer Methode nach, die einfacher zu verwenden ist und vom Framework offiziell unterstützt wird.
Wäre es nicht besser, in der Datenbank immer von der Basisdatei jeweils alles in einer zusätzlichen Collection der zusätzlichen Sprache zu speichern?