- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在根据 flutter 文档在我的应用中使用本地化。
看这里: https://flutter.dev/docs/development/accessibility-and-localization/internationalization
我使用 get_it 包(版本 4.0.4)来检索单例对象,例如本地化委托(delegate)。不幸的是它需要一个 BuildContext
属性(property)。有时在我的应用程序中我没有上下文引用,所以如果它能像这样工作就好了:GetIt.I<AppLocalizations>()
而不是这个:AppLocalizations.of(context)
.如果您像这样设置 get_it,它仍然可以毫无问题地实现:GetIt.I.registerLazySingleton(() => AppLocalizations.of(context));
问题是您至少需要一次上下文才能使其工作。此外,如果您想在初始路径中立即显示本地化文本,则很难获得正确初始化的 BuildContext
在您需要的时候。
我有点难以正确解释它,所以我在一个最小的例子中重现了这个问题。
我注释掉了一些会导致编译时错误的代码,但它显示了我想象的完成方式。
main.dart
GetIt getIt = GetIt.instance;
void setupGetIt() {
// How to get BuildContext properly if no context is available yet?
// Compile time error.
// getIt.registerLazySingleton(() => AppLocalizations.of(context));
}
void main() {
setupGetIt();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
// The above line also won't work. It has BuildContext but Applocalizations.of(context) won't work
// because it's above in the Widget tree and not yet setted up.
getIt.registerLazySingleton(() => AppLocalizations.of(context));
return MaterialApp(
supportedLocales: const [
Locale('en', 'US'),
Locale('hu', 'HU'),
],
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
localeResolutionCallback: (locale, supportedLocales) {
// check if locale is supported
for (final supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale?.languageCode &&
supportedLocale.countryCode == locale?.countryCode) {
return supportedLocale;
}
}
// if locale is not supported then return the first (default) one
return supportedLocales.first;
},
// You may pass the BuildContext here for Page1 in it's constructor
// but in a more advanced routing case it's not a maintanable solution.
home: Page1(),
);
}
}
初始路线
class PageBase extends StatelessWidget {
final String title;
final Widget content;
PageBase(this.title, this.content);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: content,
);
}
}
class Page1 extends PageBase {
// It won't run because I need the context but clearly I don't have it.
// And in a real app you also don't want to pass the context all over the place
if you have many routes to manage.
Page1(String title)
: super(AppLocalizations.of(context).title, Center(child: Text('Hello')));
// Intended solution
// I don't know how to properly initialize getIt AppLocalizations singleton by the time
// it tries to retrieve it
Page1.withGetIt(String title)
: super(getIt<AppLocalizations>().title, Center(child: Text('Hello')));
}
locales.dart
String globalLocaleName;
class AppLocalizations {
//AppLocalizations(this.localeName);
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
static Future<AppLocalizations> load(Locale locale) async {
final String name =
locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
globalLocaleName = localeName;
return AppLocalizations();
});
}
String get title => Intl.message(
'This is the title.',
name: 'title',
);
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
// This delegate instance will never change (it doesn't even have fields!)
// It can provide a constant constructor.
const _AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['en', 'hu'].contains(locale.languageCode);
}
@override
Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
还有一些intl生成的dart代码和.arb文件不是很重要,说明问题。
所以总而言之,我怎样才能使用我的 AppLocalizations
例如在这种情况下,不使用上下文就将其分类为单例?也许我最初的方法不好,可以通过我所代表的其他方式来完成。如果您有解决方案,请告诉我。
谢谢。
最佳答案
要实现您所描述的内容,您需要首先使用 get_it
创建导航服务。按照以下步骤实现结果:
import 'package:flutter/material.dart';
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState!
.push(routeName);
}
goBack() {
return navigatorKey.currentState!.pop();
}
}
这使您可以在整个应用程序中从任何位置导航到任何位置,而无需构建上下文。您可以使用此导航器键来实现当前上下文的 AppLocalization 实例。有关这种无需构建上下文的导航方法,请参阅 FilledStacks 教程。
GetIt locator = GetIt.instance;
void setupLocator() {
...
locator.registerLazySingleton(() => NavigationService());
...
}
return MaterialApp(
...
navigatorKey: navigationService.navigatorKey,
...
),
AppLocalizations
创建一个实例并将其导入到您想要使用的任何地方localeInstance() => AppLocalizations.of(locator<NavigationService>().navigatorKey.currentContext!)!;
import 'package:{your_app_name}/{location_to_this_instace}/{file_name}.dart';
localeInstance().your_localization_variable
关于Flutter - 将 GetIt 与 BuildContext 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63671225/
我按照示例项目中所示设置了所有内容: import 'package:get_it/get_it.dart'; import 'package:places/services/authService.
当应用程序在后台时,我在使用 GetIt 时遇到问题。随着应用程序处于焦点,一切都很好,但当我切换焦点时,一切都中断了。我的错误是什么? 我正在使用 GetIt 6.1.1,flutter 2.0.5
当 Delphi 崩溃时,我尝试通过 GetIt 下载 OmniThread 库。 其他软件包下载、编译和安装都很好,所以我想这是一次性的。 现在 GetIt 拒绝安装 OmniThread,因为它看
有没有办法在创建对象或从依赖注入(inject)器检索对象时将仅在运行时已知的参数传递给由 getit 依赖注入(inject)创建的对象? class WatchVideoPage extends
我正在根据 flutter 文档在我的应用中使用本地化。 看这里: https://flutter.dev/docs/development/accessibility-and-localizatio
我总是尝试禁用未使用的软件包以节省一些 IDE 内存。因此,在 XE8u1 中,我尝试通过将注册表中的“$(BDS)\Bin\GetIt220.bpl”重命名为“_GetIt”来禁用 GetIt(我从
我正在将一个大型项目迁移到 null 安全,我遇到了一个奇怪的错误,我不完全确定如何解决。 “错误:类型参数‘T’不符合‘GetIt.call’上类型变量‘T’的绑定(bind)‘Object’。”
我是一名优秀的程序员,十分优秀!