如何使用 BlockBuilder 更改应用程序语言?

How to change the application language with BlockBuilder?

应用程序需要在运行时实现语言切换。用事件和状态编写了一个 bloc,并在 main.dart 中调用了 BlocBuilder。但我不知道如何实现开关。我怎样才能做到这一点? 该应用程序总共有两种语言。 我的集团:

class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
  LanguageBloc() : super(InitialLang()) {
    on<ChangeLang>(
      (event, emit) {
        emit(NewLang());
      },
    );
  }
  
  @immutable
abstract class LanguageEvent {}

class ChangeLang extends LanguageEvent {}

@immutable
abstract class LanguageState {}

class InitialLang extends LanguageState {}
class NewLang extends LanguageState {}

我的main.dart

Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider(
          create: (context) => BottomNavyBloc(),
        ),
        BlocProvider(
          create: (context) => LanguageBloc(),
        ),
      ],
      child: BlocBuilder<LanguageBloc, LanguageState>(
        builder: (context, state) {
          return MaterialApp(
            title: 'Flutter Demo',
            localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            supportedLocales: S.delegate.supportedLocales,
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            debugShowCheckedModeBanner: false,
            home: const HomeScreen(),
          );
        },
      ),
    );
  }

我的语言按钮:

ElevatedButton(onPressed: (){}, child: Text('Switch lang'))

你可以做的是用你选择的语言发送一个变量Locale,并在你的MaterialApplocale属性,你附上。

没有并发症你可以使用Cubit而不是Bloc,因为没有必要有事件,那么你可以执行以下操作:

class LanguageCubit extends Cubit<Locale?> { // change state here, you dont use LanguageState
  LanguageCubit() : super(null);

  void initialLang () { // your initial lang
    emit(
      Locale("en", ""),
    );
  }

  void newLang(
    bool isEnglish, // in your checkbox you are gonna send the boolean value here
  ) {
    emit(
      isEnglish ? Locale("en") : Locale("fr"),
    );
  }
}

现在在您的 main 中,它只会看起来像这样:

Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider(
          create: (context) => BottomNavyBloc(),
        ),
        BlocProvider(
          create: (context) => LanguageBloc(),
        ),
      ],
      child: BlocBuilder<LanguageBloc, Locale?>( // change the state for Locale? cause could be null
        builder: (context, lang) { // different name to lang
          return MaterialApp(
            title: 'Flutter Demo',
            localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            supportedLocales: S.delegate.supportedLocales,
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            locale: lang, // here you set the lang
            debugShowCheckedModeBanner: false,
            home: const HomeScreen(),
          );
        },
      ),
    );
  }

----- 使用按钮编辑 -----

我认为您需要一个 切换按钮 来处理布尔值,但不是,您只需要一个按钮来更改它,所以我这样做了:

class _HomePageState extends State<HomePage> {
  bool _currentLanguageBool = false; // variable to know if is english or french

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
     create: (context) => LanguageCubit(), // with this we can use the Cubit in all the page, normally you have to have it in main and in the MaterialApp
     child: Scaffold(
      body: Center(
        child: ElevatedButton(
           onPressed: () {
              BlocProvider.of<LanguageCubit>(context)
                  .newLang(_currentLanguageBool);

              setState(() {
                _currentLanguageBool = !_currentLanguageBool;
              }); // with this you change the variable
            },
           child: Text('Switch lang'),
        ),
      ),
     ),
    );
  }
}

我们将使我们的小部件成为 StatefulWidget 这样我们就可以更改布尔变量并知道它是英语还是法语。如果你不想使用 Stateful 让我知道,因为我们可以将它与相同的 Cubit 一起使用,但它会改变代码和一点点 [=26] 的逻辑=]LanguageCubit.