Use of Flutter Intl

foreword

Intl is a library used in flutter to support multi-language operations, which is convenient for developers to perform localization operations through arb files, eliminating the need for some established steps.

Flutter Intl is a plug-in developed for the Intl library. Its main function is to automatically generate code, simplify pre-operations, and allow developers to focus more on arb writing;

The Flutter Intl plugin currently has a VSCode version and an IDEA/Android Studio version , and the usage steps are roughly the same.

The full name of the arb file is Application Resource Bundle (abbr. ARB), which is a localized resource format that follows the json specification. The arb file can be provided to translators and then imported separately.

Intl uses the l10n standard ( l10n is the abbreviation of localization ), the current version of the library is 0.17.0 , the operation steps may be different from the previous version, pay attention to identification.

This article demonstrates the use of the Flutter Intl plugin in the VSCode environment. The Flutter SDK version is 3.0.3, and the Dart version is 2.17.5.

Activation of the plug-in

install plugin

Search for "Intl" in the extended application market, and select "Flutter Intl" to install:
Install Intl

enable plugin

After the installation is complete, Ctrl+Shift+P opens the package command window and selects "Flutter Intl: Initialize":
intl initialization

Automatically generate related documents

The plugin will automatically generate the following directories and files in the flutter project directory:

--lib
  --l10n
    --intl_en.arb
  --generated
  	--l10n.dart
  	--intl
      --messages_all.dart
   	  --messages_en.dart

intl_en.arb is the corresponding English translation document;
l10n.dart automatically generates localization-related classes, and the class name is S by default ;
messages_en.dart maps the corresponding fields of intl_en.arb ;
messages_all.dart writes and manages messages_en.dart And the factory class of messages_xx.dart in other corresponding regions;

The call chain can be simply understood as:

l10n.dart <--messages_all.dart <--message_xx.dart <--intl_xx.arb

In addition to generating corresponding files, the plug-in will also automatically add the enable flag of intl at the end of the pubspec.yaml file :

flutter_intl:
  enabled: true

localization configuration

add dependencies

Localized dependencies need to be added in pubspec.yaml by yourself:

dependencies:
  flutter_localizations:
    sdk: flutter 

Adding to the dependencies node or dev_dependencies node depends on the situation, dependencies means project dependencies, and dev_dependencies means development environment dependencies; here, add it under the dependencies node
according to the official Flutter localization application introduction;

The dependency of the Intl library has been added to the pubspec.lock file under the action of the plugin :

  intl:
    dependency: transitive
    description:
      name: intl
      url: "https://pub.flutter-io.cn"
    source: hosted
    version: "0.17.0"

However, considering that pubspec.lock is not officially recommended as a project submission file, it is also excellent to directly depend on the pubspec.yaml file. The final dependency is as follows:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0

(After adding dependencies, you should execute the pub get packages command to remotely import related libraries, but most smart IDEs perform this process by themselves)

Add Chinese support

Ctrl+Shift+P to open the package command, select "Add Locale":
add locale
fill in the corresponding region code " zh ": after execution, the intl_zh.arb and messages_zh.dart
zh
files will be automatically generated , and the directory structure becomes:

--lib
  --l10n
    --intl_en.arb
    --intl_zh.arb
  --generated
  	--l10n.dart
  	--intl
      --messages_all.dart
   	  --messages_en.dart
   	  --messages_zh.dart
arb file operation

Add the fields that need to be mapped in the intl_en.arb file , as follows:

{
    
    
    "home": "Home",
    "about": "About",
    "greet": "Hi, {name}",
    "askChoice": "There are two choices:{one}? or {two}",
    "@askChoice": {
    
    
        "description": "Give someone two choice and wait for selection",
        "placeHolder": {
    
    
            "one": {
    
    },
            "two": {
    
    }
        }
    },
    "customDateFormat": "current date: {date}",
    "@customDateFormat": {
    
    
        "placeholders": {
    
    
            "date": {
    
    
                "type": "DateTime",
                "format": "EEE, MM/dd/yyyy",
                "isCustomDateFormat": "true"
            }
        }
    }
}

And add corresponding fields in intl_zh.arb , as follows:

{
    
    
    "home": "首页",
    "about": "关于",
    "greet": "你好, {name}",
    "askChoice": "这里有两个选择:{one}?或是 {two}",
    "@askChoice": {
    
    
        "description": "给某人两个选择,然后等待他的选择",
        "placeHolder": {
    
    
            "one": {
    
    },
            "two": {
    
    }
        }
    },
    "customDateFormat": "当前日期: {date}",
    "@customDateFormat": {
    
    
        "placeholders": {
    
    
            "date": {
    
    
                "type": "DateTime",
                "format": "EEE, MM/dd/yyyy",
                "isCustomDateFormat": "true"
            }
        }
    }
}

Ordinary fields are equivalent to [resource references], and fields starting with the "@" symbol represent rules and comments; after each update of the
intl_xx.arb file, the corresponding messages_xx.dart and the S class in l10n.dart are The corresponding field method will be automatically updated, so the mapping field can be obtained by calling the method of class S finally;

Localized entry configuration

Localization fields should be configured at the program entry or at the top level of the UI, generally at the entry of MaterialApp or WidgetsApp
; that is, localizationsDelegates and supportedLocales two fields;
the former is a proxy, which can understand the delegation that handles field mapping, and the latter is a region, that is, supports list of area codes for ;

As mentioned above, the default localization-related class S generated in l10n.dart is used here:

return MaterialApp(
      localizationsDelegates: const [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,
      //...其他代码
}

For the localization configuration of ios, you can also refer to the introduction of iOS localization in the Flutter localization application in the official document : updating the iOS app bundle .

use

Output in different locales

Finally, just call the corresponding arb field of S.current or S.of(context):

print(S.current.about);
print(S.current.greet("老哥"));
print(S.current.askChoice("确定", "取消"));
print(S.current.customDateFormat(DateTime.now()));

Output in Chinese environment:

关于
你好, 老哥
这里有两个选择:确定?或是 取消
当前日期: 周五, 07/15/2022

Output in English environment:

About
Hi, 老哥
There are two choices:确定? or 取消
current date: Fri, 07/15/2022

Of course, fields such as "OK" and "Cancel" in the above output should also be defined in advance in the arb file.

The above examples are all corresponding to the use of the message method in the Intl library. For other usages, please refer to the Intl API .

Manually specify the locale

The program will select the Locale according to the system settings, or you can specify it yourself;
for example, you can create a global class and specify the defaultLocale attribute of Intl to change the locale:

class Application {
    
    
  static Future init() async {
    
    
    Intl.defaultLocale = 'en';
  }
}

Then wrap at program entry:

Application.init().then((value) => runApp(MyApp()));

Intl.defaultLocale may not take effect on some platforms, you can try localeResolutionCallback to forcibly specify the default locale ( this method is more stable );

return MaterialApp(
      localeResolutionCallback:
          (Locale? locale, Iterable<Locale> supportedLocales) {
    
    
        var result = supportedLocales
            .where((element) => element.languageCode == locale?.languageCode);
        if (result.isNotEmpty) {
    
    
          print(locale?.languageCode);
          // return locale;
          return Locale('en');
        }
        return Locale('en');
      },
      //...其他
}

Guess you like

Origin blog.csdn.net/ifmylove2011/article/details/125797598