Flutter - 使用国际翻译对 Cubit/ Bloc 内的消息进行应用本地化

Posted

技术标签:

【中文标题】Flutter - 使用国际翻译对 Cubit/ Bloc 内的消息进行应用本地化【英文标题】:Flutter - app localization using intl translations for messages inside Cubit/ Bloc 【发布时间】:2021-04-26 20:35:54 【问题描述】:

我正在开发 Flutter 中的多语言应用程序。

按照官方文档:https://flutter.dev/docs/development/accessibility-and-localization/internationalization,在小部件/屏幕中实现本地化字符串没有问题。

但是...我的应用程序对 API 进行了很多调用,这些 API 由适当的 Cubits 和 Repositories 在幕后处理。对于这些调用和其他更深层次的逻辑,我想以适当的语言(例如小吃店)提供状态消息。我面临的问题是我无法访问 Cubits 内的本地化字符串以向州提供消息。即使我尝试将上下文传递给 Cubit,它也看不到它们。

有人有想法吗?我宁愿遵循官方方法,而不必完全重构应用程序...... 感谢期待!

【问题讨论】:

【参考方案1】:

有人帮我解决了这个问题。 解决方案很简单(ish)。 您必须将 appLocalizations 本身传递到 Cubits 中。这是我的 main.dart:

  runApp(
    MaterialApp(
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''),
        const Locale('pl', ''),
      ],
      title: 'MySuperApp',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.orange,
        accentColor: Colors.deepOrangeAccent,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      initialRoute: '/',
      routes: 
        UserAuthScreen.routeName: (context) => const UserAuthScreen(),
        HomePage.routeName: (context) => HomePage(),
        ...
      , 
      builder: (context, child) 
        final appLocalizations = AppLocalizations.of(context); //IMPORTANT
        return MultiBlocProvider(
          providers: [
            BlocProvider<ConstantsCubit>(
              lazy: true,
              create: (context) => ConstantsCubit(
                constantsRepository: ConstantsRepository(),
              ),
            ),
            BlocProvider<UserAuthCubit>(
              lazy: true,
              create: (context) => UserAuthCubit(
                localizations: appLocalizations, //THIS IS WHERE THE MAGIC HAPPENS
                repository: UserAuthRepository(),
              ),
            ),
            BlocProvider<DoerInfoCubit>(
                lazy: true,
                create: (context) => DoerInfoCubit(
                      doerInfoRepository: DoerInfoRepository(),
                      userAuthCubit: BlocProvider.of<UserAuthCubit>(context),
                    )),
            ...
          ],
          child: child,
        );
      ,
      home:
          BlocBuilder<UserAuthCubit, UserAuthState>(builder: (context, state) 
        if (state is UserAuthLogged) 
          return HomePage();
         else 
          return const UserAuthScreen();
        
      ),
    ),
  );

UserAuthCubit 声明如下所示:

class UserAuthCubit extends Cubit<UserAuthState> 
  final UserAuthRepository repository;
  final AppLocalizations localizations; //THIS IS WHERE THE MAGIC HAPPENS

  UserAuthCubit(
    @required this.repository,
    @required this.localizations,
  ) : super(const UserAuthInitial()) 
    getUserAuthState();
  

重要 - 确保解决方案有效 - 必须在 main.dart 中的 Cubits 之前声明 AppLocalizatons。 ALSO - 该应用程序在语言更改后立即在小部件中采用新的本地化。但是,通过这种设置,我无法为 Cubits 实现这一目标。他们需要重新启动应用程序。在现实生活中,这应该不是问题......我猜。

【讨论】:

以上是关于Flutter - 使用国际翻译对 Cubit/ Bloc 内的消息进行应用本地化的主要内容,如果未能解决你的问题,请参考以下文章

使用 Bloc/Cubit 进行 Flutter 状态管理

Flutter - cubit - 改变cubit内的布尔值

Flutter:单元测试一个 Cubit 问题

Flutter - Cubit 和一些需要澄清

Flutter BLoC/Cubit STATE 类最佳实践

List Cubit Flutter中的UpdateValue