Черный экран при запуске приложения при использовании i18n из JSON файлов - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь создать собственную реализацию системы локализации строк для интернационализации в приложениях Flutter, используя LocalizationsDelegate Flutter и загружая локализованные строки из файлов JSON (один файл json для каждой локали).

Все работает нормально, но когда приложение запускается, по прошествии нескольких миллисекунд экран становится черным. Причина этого заключается в том, что, поскольку я загружаю JSON файлы с использованием json.decode, способ получения локализованных строк является асинхронным. Приложение загружает свой виджет 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 и загружаю строки непосредственно оттуда, проблема с черным экраном исчезает, поскольку значения жестко закодированы и могут загружаться синхронно.

Итак, мой вопрос: как мне подождать, пока мое приложение на экране spla sh пока не будут загружены локализованные строки из файлов JSON?

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

У вас есть ошибки в ваших логах? Черный экран может быть вызван только 1. текущим маршрутом, не создающим видимую страницу, или 2. функцией build() текущих маршрутов, вызывающих исключения.

Что касается загрузки локализаций во время на spla sh экран, вы можете сделать это в вашей функции 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, находясь на экране spla sh и затем передайте его в ExampleApp, который, в свою очередь, может передать его в AppLocalizationsDelegate, который может сохранить его как локальную переменную и использовать в пределах load().

0 голосов
/ 09 марта 2020

оформить заказ пакет easy_localization , он проще, чем большинство

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...