我们在处理跨国业务、跨地区(比如港澳台)业务的时候,需要针对当地的语言来做兼容。所以,我们必须处理 ​​app​​ 的多语言。

本文,我们来讲讲,如何结合 ​​flutter_localizations​​ 和 ​​intl​​ 来实现中英文语言的切换。

项目初始化

为了演示多语言的功能,我们新建一个项目:

​flutter create jimmy_lang​

更改下代码:

// lib/main.dart

import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Multiple Languages'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Hello World!',
)
],
),
),
);
}
}

在 ​​ios​​ 模拟器上的效果:

Flutter 实现多语言_ide

我们新建了一个很简单的项目。文本 ​​Hello World!​​ 展示在屏幕的正中间。下面我们会对其进行翻译。我们会怎么做呢?请接着往下读...

更新项目 pubspec.yaml 文件

该项目的 ​​pubspec.yaml​​​ 中,添加 ​​flutter_localizations​​​ 和 ​​intl​​​ 包。并设定 ​​generate​​​ 为 ​​true​​,当项目运行起来后,生成本地化工具代码。

dependencies:
flutter:
skd: flutter
# 国际化支持
flutter_localizations:
skd: flutter
intl: ^0.17.0 # 截止更文,该包稳定版本是 0.17.0

flutter:
# 添加代码生成(合成包)支持
generate: true

添加文件 l10n.yaml

在项目的根目录(跟 ​​lib​​​ 文件夹同级)创建文件 ​​l10n.yaml​​,添加如下内容:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

​l10n.yaml​​ 配置文件的用途是:自定义生成将导入应用程序本地化类的工具。

  • ​arb-dir​​​ 指明从哪里找输入的文件,文件夹内包含的文件后缀是 ​​.arb​​。
  • ​template-arb-file​​​ 模版文件,定义翻译的元数据,该文件必须在 ​​arb-dir​​ 文件夹内创建。
  • ​output-localization-file​​​ 定义该工具将生成的主要 ​​Dart​​​ 类文件。并且应用程序将导入。所有生成的文件都是通过文件夹 ​​arb-dir​​ 下的文件生成。

创建模板 ARB 文件,比如 lib/l10n/app_en.arb

比如:

// lib/l10n/app_en.arb
{
"@@locale": "en",

"helloWorld": "Hello World!"
}

​@@locale​​​ 指明本地化的英文,当然你也可以不要这个声明。通过方法 ​​helloWorld​​​ 获取 ​​Hello World!​​ 信息。

此时运行 ​​flutter pub get​​​ 获取包,你将生成对应的 ​​dart​​ 工具:

Flutter 实现多语言_flutter_02

集成自动化生成的本地类

导入上面生成的 ​​app_localizations.dart​​​ 文件,在应用中集成 ​​AppLocalizations​​​ 类。并使用现在生成的英文本地化 ​​helloWolrd​​:

// lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // 引入对应的本地化类

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
// 添加本地化支持
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Multiple Languages'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 更改该 Text 文件内容
Text(
AppLocalizations.of(context)!.helloWorld, // 注意 !. 的使用
)
],
),
),
);
}
}

运行后,在 ​​ios​​ 模拟器上,我们依旧能得到正确的结果:

Flutter 实现多语言_Flutter_03

添加中文语言

我们来添加中文翻译。

我们添加 ​​app_zh.arb​​ 文件:

// lib/l10n/app_zh.arb
{
"@@locale": "zh",

"helloWorld": "世界,你好👋"
}

重新运行,你会发现在 ​​./dart_tool/flutter_gen/gen_l10n​​​ 中多出一份配置 ​​app_localizations_zh.dart​​ 文件 。

我们调整 ​​ios​​​ 模拟器中系统设置的语言为中文,再查看 ​​app​​。

Flutter 实现多语言_前端_04

我们 ​​Gif​​ 图走一个👇

Flutter 实现多语言_flutter_05

参考

  • ​​Guide for building internationalized Flutter apps​​