我尝试使用本地化包将Flutter中的字符串本地化。问题是需要翻译的位置。它与UI无关,而是在模型的深处,我无法访问BuildContext。还有其他可能性可以继续使用翻译功能吗?
// I don't have a context variable here
MyLocalizations.of(context).trans("foo")
Run Code Online (Sandbox Code Playgroud)
就在这里。您不需要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());
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以引用一个字符串,如下所示:
final title = Strings.current.title;
Run Code Online (Sandbox Code Playgroud)
AppLocalizations 需要上下文。
您可以创建一个类(例如,Localization)来封装 AppLocalizations 初始化,并使用其上下文从主页小部件中对其进行初始化。之后,可以与 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);
}
Run Code Online (Sandbox Code Playgroud)
在主页小部件中:
...
@override
Widget build(BuildContext context) {
Localization.init(context);
return Scaffold(
...
Run Code Online (Sandbox Code Playgroud)
使用 mixins 访问某个类中的 loc(不一定是 Widget):
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);
...
}
Run Code Online (Sandbox Code Playgroud)
空安全版本:
class Localization {
static AppLocalizations? _l;
AppLocalizations get loc => Localization._l!;
static void init(BuildContext context) => _l = AppLocalizations.of(context)!;
}
Run Code Online (Sandbox Code Playgroud)
不,没有其他方法,因为它是使用 an 存储的InheritedWidget,它是构建树的一部分,因此只能通过对它的引用 (the BuildContext)来访问。
您需要将您的信息传递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'];
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以按如下方式引用字符串:
String title = LanguageService.title;
Run Code Online (Sandbox Code Playgroud)
你可以在这里找到详细的教程
| 归档时间: |
|
| 查看次数: |
1878 次 |
| 最近记录: |