Flutter里的国际化,简言之,分为两大步:
应用内切换语言,关键点有两个:
Localizations.of<S>(context, S)
。Localizations 继承自 StatefulWidget ,内部属性 locale 有变化,child 就会重建。
以下,为国际化代码的具体实现:
在 pubspec.yaml
文件中添加它和 intl作为依赖
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any
最终的 pubspec.yaml
文件中形如:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
使用接口定义待翻译字段的好处是:实现类/子类 必须对抽象字段进行赋值,否则编译器会报错。 相比之下,字典的方式,某个 key 没有赋值,编译器检查不出来,而且,哪些 key 是有用的,哪些 key 没用了,也不好确定。
/// 本地化资源 基类
abstract class S {
/// 本地化资源代理对象
static const LocalizationsDelegate delegate = ProjectLocalizationsDelegate();
/// 根据上下文中的 [Locale] 取得对应的本地化资源。
static S of(BuildContext context) {
return Localizations.of<S>(context, S)!;
}
/// 支持的语言。
/// 如果本地没有保存的语言配置参数,APP会默认使用第一个作为默认语言。
static List<Locale> supportedLocales = [
const Locale('en'),
const Locale('ja'),
const Locale('zh')
];
// 不需要翻译的字段,直接赋值。
static String appName = 'AppName';
static String english = 'English';
static String japanese = '日本語';
static String simpleChinese = '简体中文';
static Map<String, String> localeSets = {
'en': english,
'ja': japanese,
'zh': simpleChinese
};
// 需要翻译的字段追加到下面,在子类中进行赋值。
String get cancel;
String get ok;
String get readAndAgree;
String get privacyPolicy;
String get termsOfService;
String get me;
String get settingsLanguage;
}
/// 英文
class ProjectLocalizationsEN implements S {
@override
String get cancel => "Cancel";
@override
String get ok => "OK";
}
/// 中文
class ProjectLocalizationsZH implements S {
@override
String get cancel => "取消";
@override
String get ok => "确定";
}
/// 日文
class ProjectLocalizationsJA implements S {
@override
String get cancel => "キャンセル";
@override
String get ok => "確定";
}
/// 项目本地化资源代理
class ProjectLocalizationsDelegate extends LocalizationsDelegate<S> {
const ProjectLocalizationsDelegate();
@override
bool isSupported(Locale locale) => true;
@override
Future<S> load(Locale locale) {
return SynchronousFuture<S>(getMaterialTranslation(locale));
}
@override
bool shouldReload(ProjectLocalizationsDelegate old) => false;
/// 根据 locale 得到对应的本地化资源
S getMaterialTranslation(Locale locale) {
switch (locale.languageCode) {
case 'en':
return ProjectLocalizationsEN();
case 'zh':
return ProjectLocalizationsZH();
case 'ja':
return ProjectLocalizationsJA();
default:
return ProjectLocalizationsEN();
}
}
}
import 'package:flutter_localizations/flutter_localizations.dart';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<LocaleStore>(builder: (context, localeStore, _) {
return OKToast(
movingOnWindowChange: false,
child: MaterialApp(
onGenerateTitle: (context) => S.appName, // 不需要翻译的字段,可以直接类名调用。
theme: AppTheme.lightTheme(context),
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
// 项目本地化资源代理
S.delegate,
],
// 支持的语言
supportedLocales: S.supportedLocales,
// 指定语言,如果 localStore 里没有保存的语言参数,则直接使用 S 文件中配置的第一个语言。
locale: localeStore.languageCode == null
? S.supportedLocales.first
: Locale(localeStore.languageCode!),
routes: RouteMap.routes,
home: const HomePage(),
builder: (context, child) => GestureDetector(
onTap: () => CommonUtils.hideKeyboard(context),
child: child,
),
),
);
});
}
}
S.appName
S.of(context).ok
S.of(context). cancel
功能描述 | 命令 |
---|---|
安装依赖包 | flutter pub get |
检查哪些依赖包过期 | flutter pub outdated |
检查项目依赖包是否支持空安全 | dart pub outdated --mode=null-safety |
升级依赖包 | flutter pub upgrade |
升级依赖包-大版本 | flutter pub upgrade --major-versions |
将项目代码迁移到空安全 | dart migrate |
自动修复代码问题 | dart fix --apply |
打包 Android bundle | flutter build appbundle |
打包 Android apks | flutter build apk --split-per-abi |
打包 iOS | flutter build ios |
Debug 模式运行 | flutter run |
Profile 模式运行 | flutter run --profile |
Release 模式运行 | flutter run --release |
指定 Web 渲染模式 | flutter run -d chrome --web-renderer html |
发布包检查 | flutter packages pub publish --dry-run |
发布包 | flutter packages pub publish --server=https://pub.dartlang.org |