Synopsis
This plugin helps you internationalize you Flutter app by generating be needed boiler plate code. You just add and organize strings in files that are contained in the /res/values folder. This plugin is based on the Internationalizing Flutter Apps tutorial and on the Material Library Localizations package. Much of the instructions are taken from there.
Usage
1. Setup you App
Setup your localizationsDelegates and your supportedLocales witch will allow to access the strings.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( onGenerateTitle: (BuildContext context) => S.of(context).app_name, localizationsDelegates: const >[ S.delegate, // You need to add them if you are using the material library. // The material components usses this delegates to provide default // localization GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: S.delegate.supportedLocales, title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(title: 'Flutter Demo Home Page'), ); } }
Optionally you can provide a fallback Locale for the unsupported languages. In case that the user changes the device language to an unsupported language the default resolution is:
- The first supported locale with the same Locale.languageCode.
- The first supported locale.
If you want to change the last step and to provided a default locale instead of choosing the first one in you supported list, you can specify that as fallows:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( localizationsDelegates: [ S.delegate, // You need to add them if you are using the material library. // The material components usses this delegates to provide default // localization GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: S.delegate.supportedLocales, localeResolutionCallback: S.delegate.resolution(fallback: const Locale('en', '')), // or localeListResolutionCallback: S.delegate.listResolution(fallback: const Locale('en', '')), title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(title: 'Flutter Demo Home Page'), ); } }
2. Setup the arb files.
ARB files extension stands for Application Resource Bundle and is used by the Dart intl package, it is supported by the Google Translators Toolkit and it's supported by Google.
Flutter internalization only depends on a small subset of the ARB format. Each .arb file contains a single JSON table that maps from resource IDs to localized values. Filenames contain the locale that the values have been translated for. For example material_de.arb contains German translations, and material_ar.arb contains Arabic translations. Files that contain regional translations have names that include the locale's regional suffix. For example material_en_GB.arb contains additional English translations that are specific to Great Britain.
The first English file is generated for you(/res/values/strings_en.arb). Every arb file depends on this one. If you have an a string in the German arb file(/res/values/strings_de.arb) that has an ID that is not found in the English file, it would not be listed. So you must be sure to first have the strings in the English file and then add other translations.
To add a new arb file right click on values folder and select New -> Arb File. Then pick your language from the list, and region if necessary.
1. Referencing the values
The ARB table's keys, called resource IDs, are valid Dart variable names. They correspond to methods from the S class. For example:
Widget build(BuildContext context) { return new FlatButton( child: new Text( S.of(context).cancelButtonLabel, ), ); }
2. Parametrized strings
Some strings may contain $variable tokens witch are replaced with your value. For example:
{
"aboutListTileTitle": "About $applicationName"
}
The value for this resource ID is retrieved with a parametrized method instead of a simple getter:
S.of(context).aboutListTileTitle(yourAppTitle)
3. Plurals
Plural translations can be provided for several quantities: 0, 1, 2, "few", "many", "other". The variations are identified by a resource ID suffix which must be one of "Zero", "One", "Two", "Few", "Many", "Other" (case insensitive). The "Other" variation is used when none of the other quantities apply. All plural resources must include a resource with the "Other" suffix. For example the English translations ('material_en.arb') for selectedRowCountTitle in the Material Library Localizations are:
{
"selectedRowCountTitleZero": "No items selected",
"selectedRowCountTitleMany": "to many items", //not actual real
"selectedRowCountTitleOne": "1 item selected",
"selectedRowCountTitleOther": "$selectedRowCount items selected",</pre>
}
In your code you can use this methods
S.of(context).selectedRowCountTitle("many")
or
S.of(context).selectedRowCountTitle("1")
or
S.of(context).selectedRowCountTitle("$selectedRowCount")
NOTES:
-
The plugin also supports
${variable}
notation. Use this when the parser does not catch the parameters properly. For example:{"tabLabel": "탭 $tabCount개 중 $tabIndex번째"}
will generate
String tabLabel(String tabCount개, String tabIndex번째) => "탭 $tabCount개 중 $tabIndex번째";
Witch contains invalid Dart fields. In this case you should use
{"tabLabel": "탭 ${tabCount}개 중 ${tabIndex}번째"}
-
Also you can escape the
$
sign with\
{"checkout_message": "You have to pay \$$price"}
Issues
There are some performance improvements and bug fixes that this plugin could use, so feel free to PR.