我正在尝试使用Flutter的LocalizationsDelegate
构建自己的系统来实现对Flutter应用程序中的国际化字符串的本地化,并从JSON文件(每个语言环境一个json文件)中加载本地化的字符串。
一切正常,但是启动应用程序时,屏幕变黑了几毫秒。这是因为,由于我使用json.decode
加载JSON文件,因此检索本地化字符串的方式是异步的。该应用会加载其MaterialApp
小部件和,然后开始解析JSON以进行本地化。那就是当应用程序变黑直到成功解析JSON时。
这是我的i18n系统的实现:
class Localization extends LocaleCodeAware with LocalizationsProvider {
Localization(this.locale) : super(locale.toString());
final Locale locale;
static Localization of(BuildContext context) =>
Localizations.of<Localization>(context, Localization);
}
class AppLocalizationsDelegate extends LocalizationsDelegate<Localization> {
const AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
@override
Future<Localization> load(Locale locale) async {
final localization = Localization(locale);
await localization.load();
return localization;
}
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:example/resources/asset_paths.dart' as paths;
abstract class LocaleCodeAware {
LocaleCodeAware(this.localeCode);
final String localeCode;
}
mixin LocalizationsProvider on LocaleCodeAware {
static Map<String, String> _values;
Future<void> load() async {
final string = await rootBundle.loadString('${paths.i18n}$localeCode.json');
final Map<String, dynamic> jsonMap = json.decode(string);
_values = jsonMap.map((key, value) => MapEntry(key, value.toString()));
}
String get appTitle => _values['appTitle'];
}
这是我的
main.dart
文件及其MaterialApp
小部件。import 'package:flutter/material.dart';
void main() => runApp(ExampleApp());
class ExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
localizationsDelegates: [
const AppLocalizationsDelegate(),
],
supportedLocales: const [Locale("en"), Locale("es")],
home: const AppNavigator(),
);
}
如果不是在JSON文件中使用本地化的字符串,而是将
Map<String, String>
分配给_values
映射,然后直接从那里加载字符串,那么黑屏问题就消失了,因为值是经过硬编码的并且可以同步加载。所以我的问题是,如何让我的应用程序在启动屏幕中等待,直到从JSON文件加载本地化的字符串?
最佳答案
您的日志中是否有任何错误?黑屏只能由1.当前路由未建立可见页面或2. 2.当前路由的build()
函数引发异常引起。
至于在初始屏幕上加载本地化版本,可以在main()
函数中完成:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
List<Locale> locales = WidgetsBinding.instance.window.locales;
// ... logic to decide which locale to use and load localizations for
final string = await rootBundle.loadString('${paths.i18n}$localeCode.json');
final Map<String, dynamic> jsonMap = json.decode(string);
runApp(ExampleApp(jsonMap));
}
这样,您可以在启动屏幕上读取JSON文件并将其转换为
Map
,然后将其传递给ExampleApp
,后者又可以将其传递给AppLocalizationsDelegate
,后者可以将其存储为本地变量并在load()
中使用。
关于json - 从JSON文件使用i18n时,应用启动时出现黑屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60547986/