7
votes

Comment changer la langue d'une application Flutter sans redémarrer l'application?

Dans la page des paramètres de mon application, je voudrais ajouter une option qui contrôle la langue de l'application.

Je peux définir la langue avant de démarrer l'application comme ceci:

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

Mais est-il possible de changer la langue sans redémarrer l'application?


1 commentaires

Intéressant, je me souviens sur Android C'est assez compliqué de changer de langue sans perdre son état. Mais cela pourrait être fait.


4 Réponses :


10
votes

Enveloppez votre MaterialApp dans un StreamBuilder qui sera chargé de fournir la Locale valeur à votre application. Et cela vous permettra de le changer dynamiquement sans redémarrer votre application. Voici un exemple utilisant le package rxdart pour implémenter le flux:

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      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() ;

  }

La démonstration ci-dessus n'est qu'un moyen basique de savoir comment réaliser ce que vous voulez, mais pour une mise en œuvre correcte des flux dans votre application, vous devez envisager d'utiliser des BloC à l'échelle de l'application, ce qui améliorera considérablement la qualité de votre application en réduisant le nombre de builds inutiles.


1 commentaires

mais le streamBuilder n'est pas reconstruit lorsque nous appelons setLocale depuis une autre partie de l'application



0
votes

Vous pouvez encapsuler le widget MaterialApp avec un ChangeNotifierProvider et un widget Consumer et contrôler la langue à partir du modèle.

@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),
          ....

Sur le MainModel , tout ce que vous avez à faire est de changer la variable preferredLanguageCode en ce que vous voulez ('en', 'ar', 'es', etc.). N'oubliez pas d'appeler NotifyListeners() une fois que vous avez changé la langue.

Ceci et l'autre réponse n'ont qu'un seul problème: tout context au-dessus de MaterialApp ne peut pas obtenir la langue de l'appareil (par exemple lorsque l'application est démarrée pour la première fois) avec Localizations.localeOf(context) . Cette méthode nécessitait un context MaterialApp .

Pour résoudre ce problème, j'ai utilisé ce plugin pour obtenir la langue de l'appareil sans avoir besoin d'un context .

Une fois que l'application démarre, vous pouvez changer la langue comme vous le souhaitez pour que cette approche fonctionne. J'utilise également SharedPreferences pour stocker la langue préférée une fois que l'utilisateur la modifie.


0 commentaires

8
votes

Si vous souhaitez changer la langue de l'application sans redémarrer l'application et également sans aucun plugin, vous pouvez suivre les étapes ci-dessous:

  1. Dans le fichier principal de l'application, changez la MyHomePage par défaut en StatefullWidget , dans StatefullWedget par exemple MyHomePage créez une méthode static setLocal comme suit

    Locale newLocale = Locale('ps', 'AFG');
    MyHomePage.setLocale(context, newLocale);
    

_MyHomePageState est l' state de votre widget MyHomePage

  1. Dans votre state créez un changeLanguage méthode static

     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,
          );
       }
      }
    
  2. Maintenant, à partir des pages de votre application, vous pouvez changer la langue en appelant la méthode setLocal et passer un nouveau Locale comme suit:

    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();
    }
    
  3. N'oubliez pas que vous devez créer un LocalizationDelegate ,

  4. Voici le lien vers le didacticiel écrit et l'application de démonstration


1 commentaires

Réponse très utile. Logique simple de flottement.



0
votes

Il est plus facile d'utiliser le package easy_localization .

Pour changer de langue, par exemple:

onTap: (){
 EasyLocalization.of(context).locale = Locale('en', 'US'); 
}

J'ai appris à utiliser ce package par cette vidéo: Youtube Video Link


0 commentaires