文章

05.Flutter国际化

05.Flutter国际化

国际化

flutter_localizations 包

配置

默认情况下,Flutter SDK 中的组件仅提供美国英语本地化资源(主要是文本)。要添加对其他语言的支持,应用程序须添加一个名为 “flutter_localizations” 的包依赖

1
2
3
4
5
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

下载 flutter_localizations 库,然后指定 MaterialApp 的 localizationsDelegates 和 supportedLocales:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
 localizationsDelegates: [
   // 本地化的代理类
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', 'US'), // 美国英语
    const Locale('zh', 'CN'), // 中文简体
    // 其他Locales
  ],
  // ...
)
  • localizationsDelegates 列表中的元素是生成本地化值集合的工厂类
    • GlobalMaterialLocalizations.delegate 为 Material 组件库提供的本地化的字符串和其他值,它可以使 Material 组件支持多语言
    • GlobalWidgetsLocalizations.delegate 定义组件默认的文本方向,从左到右或从右到左,这是因为有些语言的阅读习惯并不是从左到右,比如如阿拉伯语就是从右向左的
  • supportedLocales 也接收一个 Locale 数组,表示我们的应用支持的语言列表,在本例中我们的应用只支持美国英语和中文简体两种语言

获取当前区域 Locale

获取应用的当前区域 Locale:

1
2
Locale locale = Localizations.localeOf(context);
Locale? maybeLocale = Localizations.maybeLocaleOf(context);

Localizations (opens new window) 组件一般位于 widget 树中其他业务组件的顶部,它的作用是定义区域 Locale 以及设置子树依赖的本地化资源。 如果系统的语言环境发生变化,则会使用对应语言的本地化资源

监听系统语言切换

当我们更改系统语言设置时,APP 中的 Localizations 组件会重新构建,Localizations.localeOf(context) 获取的 Locale 就会更新,最终界面会重新 build 达到切换语言的效果。但是这个过程是隐式完成的,我们并没有主动去监听系统语言切换,但是有时我们需要在系统语言发生改变时做一些事,比如系统语言切换为一种我们 APP 不支持的语言时,我们需要设置一个默认的语言,这时我们就需要监听 locale 改变事件。
可以通过 MaterialApp 中的 localeResolutionCallbacklocaleListResolutionCallback 回调来监听 locale 改变的事件
localeResolutionCallback的回调函数签名:

Locale Function(Locale locale, Iterable<Locale> supportedLocales)

  • locale 参数 locale 的值为当前的当前的系统语言设置,当应用启动时或用户动态改变系统语言设置时此 locale 即为系统的当前 locale。当开发者手动指定 APP 的 locale 时,那么此 locale 参数代表开发者指定的 locale,此时将忽略系统 locale 如:
1
2
3
4
5
MaterialApp(
 // ...
 locale: const Locale('en', 'US'), //手动指定locale
 // ...
)

上面的例子中手动指定了应用 locale 为美国英语,指定后即使设备当前语言是中文简体,应用中的 locale 也依然是美国英语。如果 locale 为 null,则表示 Flutter 未能获取到设备的 Locale 信息,所以我们在使用 locale 之前一定要先判空。

  • supportedLocales 为当前应用支持的 locale 列表,是开发者在 MaterialApp 中通过 supportedLocales 属性注册的。
  • 返回值是一个 Locale,此 Locale 为 Flutter APP 最终使用的 Locale。通常在不支持的语言区域时返回一个默认的 Locale。

localeListResolutionCallback和 localeResolutionCallback 唯一的不同就在第一个参数类型,前者接收的是一个 Locale 列表,而后者接收的是单个 Locale:

Locale Function(List<Locale> locales, Iterable<Locale> supportedLocales)

在较新的 Android 系统中,用户可以设置一个语言列表,这样一来,支持多语言的应用就会得到这个列表,应用通常的处理方式就是按照列表的顺序依次尝试加载相应的 Locale,如果某一种语言加载成功则会停止。
在 Flutter 中,应该优先使用 localeListResolutionCallback,当然你不必担心 Android 系统的差异性,如果在低版本的 Android 系统中,Flutter 会自动处理这种情况,这时 Locale 列表只会包含一项

Localization 组件

Intl 包

Ref

让App支持多语言

本文由作者按照 CC BY 4.0 进行授权