如何在不重新启动应用程序的情况下更改Flutter应用程序语言?

And*_*per 2 flutter

在我的应用程序的设置页面中,我想添加一个控制应用程序语言的选项。

我可以在启动应用之前像这样设置语言:

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // other arguments
      locale: Locale('ar'),
    );
  }
Run Code Online (Sandbox Code Playgroud)

但是是否可以在不重新启动应用程序的情况下更改语言?

Sed*_*ush 19

如果您想在不重新启动应用程序并且没有任何插件的情况下更改应用程序语言,您可以按照以下步骤操作:

  1. 在应用程序的主文件中,将默认值更改MyHomePage为 a StatefullWidgetStatefullWedget例如MyHomePage创建一个static方法setLocal如下

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key}) : super(key: key);
    
       static void setLocale(BuildContext context, Locale newLocale) async {
          _MyHomePageState state = context.findAncestorStateOfType<_MyHomePageState>();
            state.changeLanguage(newLocale);
         }
    
      @override
     _MyHomePageState createState() => _MyHomePageState();
    }
    
    Run Code Online (Sandbox Code Playgroud)

这里_MyHomePageStatestate你的MyHomePage小部件

  1. 在您state创建一个static方法中changeLanguage

     class _MyHomePageState extends State<MyHomePage> {
      Locale _locale;
    
       changeLanguage(Locale locale) {
         setState(() {
          _locale = locale;
         });
        }
    
      @override
      Widget build(BuildContext context) {
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'Afghanistan',
            theme: ThemeData(primaryColor: Colors.blue[800]),
            supportedLocales: [
              Locale('fa', 'IR'),
              Locale('en', 'US'),
              Locale('ps', 'AFG'),
            ],
            locale: _locale,
            localizationsDelegates: [
              AppLocalizationsDelegate(),
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate
            ],
            localeResolutionCallback: (locale, supportedLocales) {
              for (var supportedLocale in supportedLocales) {
                if (supportedLocale.languageCode == locale.languageCode &&
                    supportedLocale.countryCode == locale.countryCode) {
                  return supportedLocale;
                }
              }
              return supportedLocales.first;
            },
            initialRoute: splashRoute,
            onGenerateRoute: Router.generatedRoute,
          );
       }
      }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在,从您的应用程序页面,您可以通过调用该setLocal方法并传递一个新的方法来更改语言,Locale如下所示:

    Locale newLocale = Locale('ps', 'AFG');
    MyHomePage.setLocale(context, newLocale);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 请记住,您需要创建一个LocalizationDelegate,

  4. 是书面教程和演示应用程序的链接

  • 看起来本教程/代码需要更新以适应新的 Flutter 更改。 (4认同)

Sar*_*ekR 9

使用easy_localization包更容易。

对于更改语言,例如:

onTap: (){
 EasyLocalization.of(context).locale = Locale('en', 'US'); 
}
Run Code Online (Sandbox Code Playgroud)

我通过这个视频学会了使用这个包:Youtube视频链接

更新:

在3.0.0版本中:

EasyLocalization.of(context).setLocale(Locale('en', '')); 
Run Code Online (Sandbox Code Playgroud)

  • 这应该与最新版本的 Easy Localization (3.0.0) EasyLocalization.of(context).setLocale(Locale('en', '')); 一起使用 (3认同)

Dpe*_*nha 6

您可以MaterialApp使用 aChangeNotifierProvider和 a Consumerwidgets 包装该 widget,并从模型中控制语言。

@override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (context) => MainModel(context: context),
      child: Consumer<MainModel>(builder: (context, mainModel, child) {
        return MaterialApp(
          locale: Locale(mainModel.preferredLanguageCode),
          ....
Run Code Online (Sandbox Code Playgroud)

在 上MainModel,您所需要做的就是将preferredLanguageCode变量更改为您想要的任何内容(“en”、“ar”、“es”等)。NotifyListeners()更改语言后,请不要忘记致电。

这个和另一个答案只有一个问题:context以上任何MaterialApp内容都无法使用Localizations.localeOf(context). 这种方法需要context吼叫MaterialApp

为了解决这个问题,我使用这个插件来获取设备语言,而不需要context.

应用程序启动后,您可以以任何您想要的方式更改语言,以使此方法发挥作用。我还用来SharedPreferences在用户更改首选语言后存储它。


Maz*_*him 5

将您包装MaterialApp成一个StreamBuilder将负责Locale为您的应用提供价值的产品。而且它将使您能够动态更改它,而无需重新启动应用程序。我使用rxdart包来实现流:

  @override
  Widget build(BuildContext context) {
    return StreamBuider(
      stream: setLocale,
      initialData: Locale('ar',''),
      builder(context, localeSnapshot){
        return MaterialApp(
          // other arguments
          locale: localeSnapshot.data,
        );
      }
    );
  }

  Stream<Locale> setLocale(int choice) {

    var localeSubject = BehaviorSubject<Locale>() ;

      choice == 0 ? localeSubject.sink.add( Locale('ar','') ) : localeSubject.sink.add( Locale('en','') ) ;


    return localeSubject.stream.distinct() ;

  }
Run Code Online (Sandbox Code Playgroud)

上面的演示只是实现所需目标的基本方法,但是要在应用中正确实现流,您应考虑使用应用范围的BloC,这将通过减少应用数量来显着提高应用质量。不必要的构建。