flutter中使用intl插件 如何实现多语言切换
- 安装intl插件
在pubspec.yaml文件中添加如下依赖:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0
执行flutter packages get命令安装依赖。
- 配置intl
在项目根目录下创建一个intl目录,然后在intl目录下创建一个arb文件,例如:
{
"title": "Flutter 多语言切换示例",
"@title": {
"description": "App 标题"
},
"hello": "你好,{name}!",
"@hello": {
"description": "欢迎语"
}
}
其中,title和hello是要翻译的文本,{name}是一个占位符。
- 生成本地化资源
在终端中执行如下命令:
flutter pub pub run intl_translation:extract_to_arb --output-dir=intl/arb --locale=zh_CN lib/main.dart
其中,--locale参数指定目标语言,lib/main.dart是要翻译的源代码文件。
执行完命令后,会在intl/arb目录下生成一个messages.arb文件,用翻译工具翻译其中的文本。
- 生成本地化文件
在终端中执行如下命令:
flutter pub pub run intl_translation:generate_from_arb --output-dir=intl --no-use-deferred-loading lib/main.dart intl/arb/messages_*.arb
执行完命令后,会在intl目录下生成多个语言的本地化文件,例如:
intl_en.arb
intl_zh_CN.arb
intl_messages_all.dart
intl_messages_en.dart
intl_messages_zh_CN.dart
其中,intl_messages_all.dart是一个包含所有语言的本地化文件,intl_messages_en.dart和intl_messages_zh_CN.dart是单独的语言本地化文件。
- 实现多语言切换
在main.dart中添加如下代码:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
import 'intl/intl_messages_all.dart';
void main() {
// 设置默认语言
Intl.defaultLocale = 'zh_CN';
// 注册本地化资源
initializeMessages('zh_CN').then((_) {
runApp(MyApp());
});
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: Intl.message('title'),
localizationsDelegates: [
// 注册本地化代理
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
// 注册自定义本地化代理
MyLocalizationsDelegate(),
],
supportedLocales: [
const Locale('en', ''),
const Locale('zh', 'CN'),
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
final nameController = TextEditingController();
@override
Widget build(BuildContext context) {
final name = nameController.text;
return Scaffold(
appBar: AppBar(
title: Text(Intl.message('title')),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
Intl.message('hello', args: [name]),
style: Theme.of(context).textTheme.headline4,
),
TextField(
controller: nameController,
decoration: InputDecoration(
hintText: Intl.message('请输入您的姓名'),
),
),
],
),
),
);
}
}
class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations> {
@override
bool isSupported(Locale locale) {
return ['en', 'zh'].contains(locale.languageCode);
}
@override
Future<MyLocalizations> load(Locale locale) async {
final localeName = Intl.canonicalizedLocale(locale.toString());
await initializeMessages(localeName);
Intl.defaultLocale = localeName;
return MyLocalizations();
}
@override
bool shouldReload(covariant LocalizationsDelegate<MyLocalizations> old) {
return false;
}
}
class MyLocalizations {
static Future<MyLocalizations> load(Locale locale) {
final name = Intl.canonicalizedLocale(locale.toString());
final lookup = MessageLookupByLibrary(IntlMessagesAll.instance);
return initializeMessages(name).then((_) {
return MyLocalizations();
});
}
static MyLocalizations of(BuildContext context) {
return Localizations.of<MyLocalizations>(context, MyLocalizations);
}
String get title => Intl.message('title');
String hello(String name) => Intl.message('hello', args: [name]);
}
其中,GlobalMaterialLocalizations.delegate和GlobalWidgetsLocalizations.delegate是Flutter自带的本地化代理,用来实现Flutter自带组件的本地化。
MyLocalizationsDelegate是自定义的本地化代理,用来实现自定义组件的本地化。
MyLocalizations是自定义的本地化类,用来提供本地化文本的访问接口。
在需要使用本地化文本的地方,可以使用MyLocalizations.of(context)来获取MyLocalizations实例,然后调用其提供的本地化文本访问接口即可。
- 切换语言
在MyLocalizationsDelegate类中,可以添加一个静态方法来切换语言,例如:
class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations> {
...
static Future<void> setLocale(Locale locale) async {
final localeName = Intl.canonicalizedLocale(locale.toString());
await initializeMessages(localeName);
Intl.defaultLocale = localeName;
}
}
然后在需要切换语言的地方调用该静态方法即可,例如:
MyLocalizationsDelegate.setLocale(Locale('en', ''));
原文地址: https://www.cveoy.top/t/topic/bUu7 著作权归作者所有。请勿转载和采集!