Не удается получить новое состояние в BlocListener из-за локализаций - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть приложение с blo c и локализацией. Мое приложение загружает SplashPage, пока все не будет готово, и после этого оно меняет страницу. Все хорошо и очевидно без локализаций (без supportedLocales, localizationsDelegates и localeResolutionCallback в MaterialApp), но при включении новое состояние bloc не будет получено BlocListener и SplashPage не изменится на FirstPage.

main.dart:

void main() => runApp(BlocProvider<MainBloc>(
    create: (_) => MainBloc(),
    child: MyApp()
));

class MyApp extends StatefulWidget {

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  MainBloc _mainBloc;
  final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();

  @override
  void initState() {
    super.initState();

    _mainBloc = BlocProvider.of<MainBloc>(context);
    _mainBloc.add(ReadyEvent());
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        supportedLocales: [
          Locale('en', 'US'),
          Locale('sk', 'SK'),
        ],
        localizationsDelegates: [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        localeResolutionCallback: (locale, supportedLocales) {
          Locale usedLocale;
          for (var supportedLocale in supportedLocales) {
            if (supportedLocale.languageCode == locale.languageCode &&
                supportedLocale.countryCode == locale.countryCode) {
              usedLocale = supportedLocale;
              break;
            }
          }
          if(usedLocale == null)
            usedLocale = supportedLocales.first;
          return usedLocale;
        },
        home: Scaffold(
          body: BlocListener<MainBloc, MainState>(
            listener: (context, state){
              if(state is ReadyState){
                print('Go to first_page');
                rootNavigatorKey.currentState.pushNamedAndRemoveUntil("first_page", (r) => false);
              }
            },
            child: Navigator(
              key: rootNavigatorKey,
              initialRoute: 'splash_page',
              onGenerateRoute: RouteGenerator.generateRoute,
            ),
          ),
        )
    );
  }
}

app_localizations.dart:

class AppLocalizations {
  final Locale locale;

  AppLocalizations(this.locale);

  // Helper method to keep the code in the widgets concise
  // Localizations are accessed using an InheritedWidget "of" syntax
  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

  // Static member to have a simple access to the delegate from the MaterialApp
  static const LocalizationsDelegate<AppLocalizations> delegate =
  _AppLocalizationsDelegate();

  Map<String, String> _localizedStrings;

  Future<bool> load() async {
    // Load the language JSON file from the "lang" folder
    String jsonString =
    await rootBundle.loadString('lang/${locale.languageCode}.json');
    Map<String, dynamic> jsonMap = json.decode(jsonString);

    _localizedStrings = jsonMap.map((key, value) {
      return MapEntry(key, value.toString());
    });

    return true;
  }

  // This method will be called from every widget which needs a localized text
  String translate(String key) {
    return _localizedStrings[key];
  }
}

// LocalizationsDelegate is a factory for a set of localized resources
// In this case, the localized strings will be gotten in an AppLocalizations object
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) {
    // Include all of your supported language codes here
    return ['en', 'sk'].contains(locale.languageCode);
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    // AppLocalizations class is where the JSON loading actually runs
    AppLocalizations localizations = new AppLocalizations(locale);
    await localizations.load();
    return localizations;
  }

  @override
  bool shouldReload(_AppLocalizationsDelegate old) => false;
}

route_generator.dart:

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case 'splash_page':
        return MaterialPageRoute(builder: (_) => SplashPage());
      case 'first_page':
        return MaterialPageRoute(builder: (_) => FirstPage());
    }
  }

}

Вы также можете проверить минимальный рабочий пример здесь.

Также я нашел та же проблема здесь , но, к сожалению, опубликованное решение не работает.

Как я могу это исправить?

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