Flutter:多语言应用程序 - 如何覆盖语言环境?
Flutter: Multi-lingual application - how to override the locale?
我按照官方 Flutter 页面中给出的解释(参见 here)使我的应用程序可以使用不同的语言。
根据文档,它会检索用户的语言环境,这工作正常。
现在假设我的应用程序支持不同的语言(例如 EN、FR、ES 等),并且用户可以 select 这些语言中的一种来使用该应用程序(selected 语言将不同于 phone 设置中定义的语言),我该如何实现?
我如何强制应用程序语言环境和动态"reload"所有翻译?
Flutter 页面没有对此进行解释,我在文档中也没有看到任何对我有帮助的内容...
这是当前的实现:
class Translations {
Translations(this.locale);
final Locale locale;
static Translations of(BuildContext context){
return Localizations.of<Translations>(context, Translations);
}
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'title': 'Hello',
},
'fr': {
'title': 'Bonjour',
},
'es': {
'title': 'Hola',
}
};
String text(String key){
return _localizedValues[locale.languageCode][key] ?? '** ${key} not found';
}
}
class TranslationsDelegate extends LocalizationsDelegate<Translations> {
const TranslationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'fr','es'].contains(locale.languageCode);
@override
Future<Translations> load(Locale locale) {
return new SynchronousFuture<Translations>(new Translations(locale));
}
@override
bool shouldReload(TranslationsDelegate old) => false;
}
在main.dart中:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: Translations.of(context).text('title'),
theme: new ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
const TranslationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('fr', ''), // French
const Locale('fr', ''), // French
],
home: new LandingPage(),
);
}
}
非常感谢您的帮助。
这可以通过
来完成
- 创建一个新的 LocalizationsDelegate,它可以转换为
单一语言环境或完全延迟取决于参数
- 将基础应用程序 (MyApp) 转换为有状态小部件并将上面的新委托插入 localizationsDelegates 列表
- 使用基于某些事件针对特定语言环境的新委托管理基本应用程序 (MyApp) 状态
1) 的简单实现可能是:
class SpecifiedLocalizationDelegate
extends LocalizationsDelegate<Translations> {
final Locale overriddenLocale;
const SpecifiedLocalizationDelegate(this.overriddenLocale);
@override
bool isSupported(Locale locale) => overriddenLocale != null;
@override
Future<Translations> load(Locale locale) =>
Translations.load(overriddenLocale);
@override
bool shouldReload(SpecifiedLocalizationDelegate old) => true;
}
接下来是 2) 和 3),将 MyApp 转换为有状态并包含新的委托(最初只是推迟所有内容),加上一些事件处理程序以使用指定新区域设置的新委托更改状态。
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
SpecifiedLocalizationDelegate _localeOverrideDelegate;
@override
void initState() {
super.initState();
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(null);
}
onLocaleChange(Locale l) {
setState(() {
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(l);
});
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
localizationsDelegates: [
_localeOverrideDelegate,
const TranslationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('fr', ''), // French
],
home: new LandingPage(onLocaleSwitch: onLocaleChange),
);
}
}
通过这些更改,您现在可以在子窗口小部件中使用 Translations.of(context).myLocalizedString
检索翻译。
更完整的要点:https://gist.github.com/ilikerobots/474b414138f3f99150dbb3d0cc4cc721
要控制应用程序的语言环境,您可以使用 MaterialApp 的 locale 属性:
return MaterialApp(
...
locale: _myLocal,
...
);
这与@ilikerobots StatefulWidget 方法相结合将为您提供所需的东西。
使用 Providers 中的一种应该可以完成这项工作,我对提供商不是很熟悉,但这让我工作起来很轻松
- 使用 ChangeNotifierProvider
包装您的 material 应用
return ChangeNotifierProvider(
create: (_) => new LocaleModel(),
child: Consumer<LocaleModel>(
builder: (context, provider, child) => MaterialApp(
title: 'myapp',
locale: Provider.of<LocaleModel>(context).locale
...
...
...
- 使用 getter 和 setter 创建模型 class 以获取和设置区域设置为\
import 'package:iborganic/const/page_exports.dart';
class LocaleModel with ChangeNotifier {
Locale locale = Locale('en');
Locale get getlocale => locale;
void changelocale(Locale l) {
locale = l;
notifyListeners();
}
}
- 更改某些事件的语言环境(单击按钮) as
Provider.of<LocaleModel>(context).changelocale(Locale("kn"));
将 material 应用包装在 Provider 中的好处是您可以从应用的任何部分访问语言环境值
最简单的方法是使用语言环境 属性,国际化教程中没有提到这一点很奇怪。 MaterialApp class 的 属性 允许我们立即指定我们希望我们的应用程序使用的语言环境
return MaterialApp(
locale: Locale('ar', ''),
localizationsDelegates: [
MyLocalizationsDelegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('ar', ''), // Arabic
],
home: HomeScreen()
);
This tutorial explained it better
它还解释了如何从 sharedPreferences 加载语言环境首选项
我按照官方 Flutter 页面中给出的解释(参见 here)使我的应用程序可以使用不同的语言。
根据文档,它会检索用户的语言环境,这工作正常。
现在假设我的应用程序支持不同的语言(例如 EN、FR、ES 等),并且用户可以 select 这些语言中的一种来使用该应用程序(selected 语言将不同于 phone 设置中定义的语言),我该如何实现?
我如何强制应用程序语言环境和动态"reload"所有翻译?
Flutter 页面没有对此进行解释,我在文档中也没有看到任何对我有帮助的内容...
这是当前的实现:
class Translations {
Translations(this.locale);
final Locale locale;
static Translations of(BuildContext context){
return Localizations.of<Translations>(context, Translations);
}
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'title': 'Hello',
},
'fr': {
'title': 'Bonjour',
},
'es': {
'title': 'Hola',
}
};
String text(String key){
return _localizedValues[locale.languageCode][key] ?? '** ${key} not found';
}
}
class TranslationsDelegate extends LocalizationsDelegate<Translations> {
const TranslationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'fr','es'].contains(locale.languageCode);
@override
Future<Translations> load(Locale locale) {
return new SynchronousFuture<Translations>(new Translations(locale));
}
@override
bool shouldReload(TranslationsDelegate old) => false;
}
在main.dart中:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: Translations.of(context).text('title'),
theme: new ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
const TranslationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('fr', ''), // French
const Locale('fr', ''), // French
],
home: new LandingPage(),
);
}
}
非常感谢您的帮助。
这可以通过
来完成- 创建一个新的 LocalizationsDelegate,它可以转换为 单一语言环境或完全延迟取决于参数
- 将基础应用程序 (MyApp) 转换为有状态小部件并将上面的新委托插入 localizationsDelegates 列表
- 使用基于某些事件针对特定语言环境的新委托管理基本应用程序 (MyApp) 状态
1) 的简单实现可能是:
class SpecifiedLocalizationDelegate
extends LocalizationsDelegate<Translations> {
final Locale overriddenLocale;
const SpecifiedLocalizationDelegate(this.overriddenLocale);
@override
bool isSupported(Locale locale) => overriddenLocale != null;
@override
Future<Translations> load(Locale locale) =>
Translations.load(overriddenLocale);
@override
bool shouldReload(SpecifiedLocalizationDelegate old) => true;
}
接下来是 2) 和 3),将 MyApp 转换为有状态并包含新的委托(最初只是推迟所有内容),加上一些事件处理程序以使用指定新区域设置的新委托更改状态。
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
SpecifiedLocalizationDelegate _localeOverrideDelegate;
@override
void initState() {
super.initState();
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(null);
}
onLocaleChange(Locale l) {
setState(() {
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(l);
});
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
localizationsDelegates: [
_localeOverrideDelegate,
const TranslationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('fr', ''), // French
],
home: new LandingPage(onLocaleSwitch: onLocaleChange),
);
}
}
通过这些更改,您现在可以在子窗口小部件中使用 Translations.of(context).myLocalizedString
检索翻译。
更完整的要点:https://gist.github.com/ilikerobots/474b414138f3f99150dbb3d0cc4cc721
要控制应用程序的语言环境,您可以使用 MaterialApp 的 locale 属性:
return MaterialApp(
...
locale: _myLocal,
...
);
这与@ilikerobots StatefulWidget 方法相结合将为您提供所需的东西。
使用 Providers 中的一种应该可以完成这项工作,我对提供商不是很熟悉,但这让我工作起来很轻松
- 使用 ChangeNotifierProvider 包装您的 material 应用
return ChangeNotifierProvider(
create: (_) => new LocaleModel(),
child: Consumer<LocaleModel>(
builder: (context, provider, child) => MaterialApp(
title: 'myapp',
locale: Provider.of<LocaleModel>(context).locale
...
...
...
- 使用 getter 和 setter 创建模型 class 以获取和设置区域设置为\
import 'package:iborganic/const/page_exports.dart';
class LocaleModel with ChangeNotifier {
Locale locale = Locale('en');
Locale get getlocale => locale;
void changelocale(Locale l) {
locale = l;
notifyListeners();
}
}
- 更改某些事件的语言环境(单击按钮) as
Provider.of<LocaleModel>(context).changelocale(Locale("kn"));
将 material 应用包装在 Provider 中的好处是您可以从应用的任何部分访问语言环境值
最简单的方法是使用语言环境 属性,国际化教程中没有提到这一点很奇怪。 MaterialApp class 的 属性 允许我们立即指定我们希望我们的应用程序使用的语言环境
return MaterialApp(
locale: Locale('ar', ''),
localizationsDelegates: [
MyLocalizationsDelegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English
const Locale('ar', ''), // Arabic
],
home: HomeScreen()
);
This tutorial explained it better
它还解释了如何从 sharedPreferences 加载语言环境首选项