我尝试使用Flutter的本地化包来本地化字符串。问题在于需要翻译的位置不涉及UI,而是在我的模型中深处,我无法访问BuildContext。是否有其他可能性仍然可以使用翻译函数?
// I don't have a context variable here
MyLocalizations.of(context).trans("foo")
有的。你不需要BuildContext来访问字符串。这是我的解决方案:
是的,有。您不需要BuildContext来访问字符串。以下是我的解决方案:
class Strings {
Strings._(Locale locale) : _localeName = locale.toString() {
current = this;
}
final String _localeName;
static Strings current;
static Future<Strings> load(Locale locale) async {
await initializeMessages(locale.toString());
final result = Strings._(locale);
return result;
}
static Strings of(BuildContext context) {
return Localizations.of<Strings>(context, Strings);
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title for the Demo application',
);
}
}
Future<Null> main() async {
final Locale myLocale = Locale(window.locale);
await Strings.load(myLocale);
runApp(MyApplication());
}
现在您可以按照以下方式引用字符串:
final title = Strings.current.title;
Strings.load
来在运行时更改当前的语言,那么你需要重新加载存储在类成员数据中的任何字符串。如果你将字符串存储在静态 final 变量中,则需要重新启动应用程序。目前没有其他问题。 - kinePlatform.locale
传递给了语言环境构造函数。我没有测试过这个,我的示例代码使用的是 window.locale
。请尝试使用它再次测试,并从设备设置中更改语言。 - kineAppLocalitzations 需要上下文。
你可以创建一个类(例如 Localization)来封装 AppLocalizations 的初始化,并使用它的上下文从主页widget中进行初始化。之后,可以使用 mixin 进行操作:
import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class Localization {
static AppLocalizations _loc;
AppLocalizations get loc => Localization._loc;
static void init(BuildContext context) => _loc = AppLocalizations.of(context);
}
在首页小部件中:
...
@override
Widget build(BuildContext context) {
Localization.init(context);
return Scaffold(
...
使用mixins在某个类中(不一定是Widget)访问loc:
class XXXWidget extends StatelessWidget with Localization {
...
Text(loc.xxxx)
...
}
class _XXXXWidgetState extends State<XXXWidget> with Localization {
...
Text(loc.xxxx)
...
}
class XXXXController with Localization {
...
cardNumberValidator = RequiredValidator(errorText: loc.commons_Required);
...
}
空安全版本:
class Localization {
static AppLocalizations? _l;
AppLocalizations get loc => Localization._l!;
static void init(BuildContext context) => _l = AppLocalizations.of(context)!;
}
我知道这个问题已经很久了。但是在实现我的应用程序时,我遇到了这个问题,我没有看到任何“好”的方式来处理它。 所以这里是我的方法。
class LanguageService {
static String defaultLanguage = 'en';
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'title': 'Storefront',
'language': 'Language',
'googleLogin': 'Login with Google'
},
'vn': {
'title': 'Cửa hàng',
'language': 'Ngôn ngữ',
'googleLogin': 'Đăng Nhập với Google'
}
};
static set language(String lang) {
defaultLanguage = lang;
}
static String get title {
return _localizedValues[defaultLanguage]['title'];
}
static String get language {
return _localizedValues[defaultLanguage]['language'];
}
static String get googleLogin {
return _localizedValues[defaultLanguage]['googleLogin'];
}
}
现在你可以按如下方式引用字符串:
String title = LanguageService.title;
我不确定我是否从性能角度做得正确,也许有人可以对此发表评论,但是我在我的AppLocalization中使用了rx BehaviorSubject,并在加载新语言环境时触发事件。我在main.dart中监听它,并在接收到事件时进行setState操作。 我检查了性能选项卡,但是与通过上下文(继承小部件)访问翻译的方法相比,没有注意到任何大的变化。
BuildContext
。 - Rémi RousseletBuildContext context
,那么它怎么能工作呢? - Daniel StephensBuildContext get context => _element;
,所以可以在构建上下文之外使用上下文。这可能确实有所帮助。我会看一下,谢谢! - Daniel Stephensbuild
方法中,它接收一个BuildContext
参数,您可以获取本地化内容:Widget build(BuildContext context) { var loc = MyLocalizations.of(context); … }
然后只需将其作为参数传递给从那里调用的任何其他函数。 - Derek Lakin