由于本地化,无法在BlocListener中获得新状态

时间:2020-04-18 15:37:13

标签: flutter dart bloc

我有一个带有bloc和本地化版本的应用程序。我的应用会加载SplashPage,直到一切准备就绪,然后它会更改页面。一切都很好并且很明显,没有本地化(supportedLocales中没有localizationsDelegateslocaleResolutionCallbackMaterialApp),但是当它打开时,新的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());
    }
  }

}

您还可以选中minimal working example here.

我还发现了the same issue here,但不幸的是发布的解决方案不起作用。

我该如何解决?

0 个答案:

没有答案