json - 从JSON文件使用i18n时,应用启动时出现黑屏

标签 json flutter dart internationalization

我正在尝试使用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/

相关文章:

javascript - 在javascript中解析json格式

c# - MVC Controller 返回内容与返回 Json Ajax

java - Bean 访问器的 Genson 缓存

Flutter 如何画半圆(半圆)

java - 选择状态后使用 notifyDataSetChanged 更新 City Spinner

java - Flutter:如何在 Apple M1 芯片中安装 Flutter 及其所需的 SDK 元素?

android - 在 flutter 中运行后台进程,当应用程序关闭时显示通知和点击 API,

flutter - Flutter-自定义Flutter相机插件

dart - 在 pub 构建期间关闭 dart2js

flutter - 使用 Cubit Bloc 更新另一个小部件