Schaltfläche zum Ändern der Sprache Flutter

Lesezeit: 12 Minuten

Ich erstelle eine App in Flutter. Bisher verwende ich die Internationalisierung mit JSON, wobei die Sprache der App auf der Sprache basiert, die der Benutzer standardmäßig auf seinem Telefon hat. Es funktioniert ziemlich gut, aber ich möchte es dem Benutzer geben Eine Möglichkeit, die Sprache zu ändern, ohne die Systemspracheneinstellungen des Telefons zu ändern, indem Sie einfach auf eine Schaltfläche klicken und dann die Anwendung die Sprache ändern, ohne die Einstellungen durchgehen zu müssen.

Hier ist der Code:

Das Wichtigste:

import 'package:flutter/material.dart';
import 'package:flutter_app_darkmode/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

  void main() => runApp(MyApp());

  class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) => MaterialApp(
      supportedLocales: [
      Locale('en', "ZA"),
      Locale('pt', "MZ"),
      ],
      localizationsDelegates: [
      AppLocalizations.delegate,
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate
      ],
      localeResolutionCallback: (locale, supportedLocales) {
       for (var supportedLocale in supportedLocales) {
        if (supportedLocale.languageCode == locale.languageCode &&
            supportedLocale.countryCode == locale.countryCode) {
          return supportedLocale;
          } else {
          if (MyHomePage.local != null) {
            for (int i = 0; i < supportedLocales.length; i++) {
              if (MyHomePage.local == supportedLocales.elementAt(i)) {
                return supportedLocales.elementAt(i);
              }}}}}
            return supportedLocales.first;
            },
           home: MyHomePage(),
          );}

         class MyHomePage extends StatefulWidget {
         @override
         _MyHomePageState createState() => _MyHomePageState();

           class _MyHomePageState extends State<MyHomePage> {
           getLocale() {
           Locale myLocale = Localizations.localeOf(context);
            print(myLocale);}

            @override
             Widget build(BuildContext context) {
              getLocale();
               return Scaffold(
                body: Center(
                child: Padding(
                 padding: const EdgeInsets.all(8.0),
                  child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                   Text(
                   AppLocalizations.of(context).translate('first_string'),
                   style: TextStyle(fontSize: 25),
                   textAlign: TextAlign.center,),
                  Text(
                  AppLocalizations.of(context).translate('second_string'),
                    style: TextStyle(fontSize: 25),
                    textAlign: TextAlign.center,),
                    RaisedButton(
                      child: Text('PT'),
                    onPressed: () {},
                     ),],),),),);}}

Die app_locations-Klasse:

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class AppLocalizations {
final Locale locale;

  AppLocalizations(this.locale);

  static AppLocalizations of(BuildContext context) {
   return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

    static const LocalizationsDelegate<AppLocalizations> delegate =
    _AppLocalizationsDelegate();

    Map<String, String> _localizedStrings;

       Future<bool> load() async {
       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;}

       String translate(String key) {
      return _localizedStrings[key];}}

     class _AppLocalizationsDelegate
     extends LocalizationsDelegate<AppLocalizations> {
     const _AppLocalizationsDelegate();

       @override
       bool isSupported(Locale locale) {
       return ['en', 'pt'].contains(locale.languageCode);}

       @override
       Future<AppLocalizations> load(Locale locale) async {
       AppLocalizations localizations = new AppLocalizations(locale);
       await localizations.load();
       return localizations;}

        @override
        bool shouldReload(_AppLocalizationsDelegate old) => false;}

  • Das könnte für Sie hilfreich sein,Developerlibs.com/2019/03/…

    – Shirsh Shukla

    18. Dezember 2020 um 12:14 Uhr

  • Ich würde empfehlen, sich das Get-Paket anzusehen: pub.dev/packages/get. Die Internationalisierungsunterstützung ist recht robust und einfach zu verwenden. Weitere Informationen finden Sie hier: pub.dev/packages/get#internationalization. Sobald Sie die Schaltfläche gedrückt haben, können Sie die unter „Gebietsschema ändern“ beschriebene Methode verwenden, um die Übersetzungen zu ändern.

    – Tanay Neotia

    19. Dezember 2020 um 20:24


  • Ich würde Folgendes vorschlagen: medium.com/@puneetsethi25/…

    – puspak saha

    23. Dezember 2020 um 12:01 Uhr

Benutzer-Avatar von spkersten
sprecher

Sie können das einstellen locale Eigentum von MaterialApp mit Ihrer bevorzugten Zustandsverwaltungsmethode. Zum Beispiel:

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();

  static _MyAppState of(BuildContext context) => context.findAncestorStateOfType<_MyAppState>();
}

class _MyAppState extends State<MyApp> {
  Locale _locale;

  void setLocale(Locale value) {
    setState(() {
      _locale = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: _locale,
      home: Dashboard(),
    );
  }
}

class Dashboard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextButton(
          child: Text("Set locale to German"),
          onPressed: () => MyApp.of(context).setLocale(Locale.fromSubtags(languageCode: 'de')),
        ),
        TextButton(
          child: Text("Set locale to English"),
          onPressed: () => MyApp.of(context).setLocale(Locale.fromSubtags(languageCode: 'en')),
        ),
      ],
    );
  }
}

  • Das hat bei mir funktioniert! Mit einer kleinen Änderung: Ich konnte es nicht zum Laufen bringen, wenn meine FlutterApp ein StatfulWidget (z. B. MyApp) als Haupt-„Zuhause“ hatte. Also habe ich das zustandsbehaftete MyApp-Widget in ein zustandsloses Widget (z. B. MyAppWrapper) verpackt. Das Einzige, was der MyAppWrapper tut, ist, dass er über eine Build-Methode verfügt, die MyApp() zurückgibt.

    – drpawelo

    2. Juli 2021 um 16:16 Uhr

  • Aber das würde App-Neustarts nicht überleben, oder?

    – Marcus

    16. Juli 2021 um 16:51 Uhr

  • @Marcus Es übersteht App-Neustarts tatsächlich nicht. Sie müssten die Daten beibehalten.

    – Lautsprecher

    12. August 2021 um 11:51 Uhr

  • Jedes Beispiel, das die Änderungen beibehält

    – LearnFlutter

    12. April 2022 um 13:07 Uhr

  • @LearnFlutter, du könntest das verwenden Gemeinsame Einstellungen Verpacken Sie die Daten und behalten Sie sie dort bei, wenn sich die Auswahl ändert. Um die Daten dann zu lesen, könnten Sie Folgendes tun: @override void didChangeDependencies() { SharedPreferencesHelper.getLanguageCode().then((languageCode) { setState(() { _locale = Locale(languageCode); }); }); super.didChangeDependencies(); }

    – Sam Bains

    21. Mai 2022 um 9:17 Uhr


Benutzeravatar von Balaji Venkatraman
Balaji Venkatraman

Sie müssen die von Flutter bereitgestellten Lokalisierungen verwenden. Sie müssen benutzerdefinierte Delegate- und JSON-Dateien für Ihre unterstützten Sprachen verwenden. Ich habe mit implementiert bloc

Schritte zum folgen,

  1. Erstellen Sie einen Ordner assets/languages/ im Stammordner
  2. Erstellen JSON Dateien für Ihre unterstützten Sprachen. Wie: en.json, es.json
  3. Erstellen Sie in jeder Datei ein Schlüssel-Wert-Paar für Ihre Zeichenfolgen entsprechend den jeweiligen Sprachzeichenfolgen
  4. In main.dart Standard erstellen locale, supportedLocales and localizationsDelegates.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

import 'package:movie_app/common/constants/languages.dart';
import 'package:movie_app/presentation/app_localizations.dart';
import 'package:movie_app/presentation/blocs/language/language_bloc.dart';
import 'package:movie_app/presentation/journeys/home/home_screen.dart';

class MovieApp extends StatefulWidget {
  @override
  _MovieAppState createState() => _MovieAppState();
}

class _MovieAppState extends State<MovieApp> {
  LanguageBloc _languageBloc;

  @override
  void initState() {
    _languageBloc = LanguageBloc();
    super.initState();
  }

  @override
  void dispose() {
    _languageBloc.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<LanguageBloc>.value(
      value: _languageBloc,
      child: BlocBuilder<LanguageBloc, LanguageState>(
        builder: (context, state) {
          if (state is LanguageLoaded) {
            return MaterialApp(
                debugShowCheckedModeBanner: false,
                title: 'Movie App',
                home: HomeScreen(),
                supportedLocales:
                    Languages.languages.map((e) => Locale(e.code)).toList(),
                locale: state.locale,
                localizationsDelegates: [
                  AppLocalizations.delegate,
                  GlobalMaterialLocalizations.delegate,
                  GlobalWidgetsLocalizations.delegate,
                ],
              );
          }
          return SizedBox.shrink();
        },
      ),
    );
  }
}
  1. Erstellen Sie nun Languages-Sprachmodelle und -Konstanten
class LanguageEntity {
  final String code;
  final String value;

  const LanguageEntity({
     this.code,
     this.value,
  });
}

class Languages {
  const Languages._();

  static const languages = [
    LanguageEntity(code: 'en', value: 'English'),
    LanguageEntity(code: 'es', value: 'Spanish'),
  ];
}

  1. Erstellen Sie nun einen Delegierten für die App-Lokalisierung
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:movie_app/common/constants/languages.dart';

class AppLocalizations {
  final Locale locale;

  AppLocalizations(this.locale);

  static const LocalizationsDelegate<AppLocalizations> delegate =
      _AppLocalizationDelagate();

  static AppLocalizations of(context) =>
      Localizations.of<AppLocalizations>(context, AppLocalizations);

  Map<String, String> _localisedString;

  Future<bool> load() async {
    final jsonString = await rootBundle
        .loadString('assets/languages/${locale.languageCode}.json');
    final Map<String, dynamic> jsonMap = json.decode(jsonString);
    _localisedString =
        jsonMap.map((key, value) => MapEntry(key, value.toString()));
    return true;
  }

  String translate(String key) {
    return _localisedString[key];
  }
}

class _AppLocalizationDelagate extends LocalizationsDelegate<AppLocalizations> {
  const _AppLocalizationDelagate();

  @override
  bool isSupported(Locale locale) {
    return Languages.languages
        .map((e) => e.code)
        .toList()
        .contains(locale.languageCode);
  }

  @override
  bool shouldReload(covariant LocalizationsDelegate old) {
    return false;
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    AppLocalizations appLocalizations = AppLocalizations(locale);
    await appLocalizations.load();
    return appLocalizations;
  }
}
  1. Erstellen Sie nun Blöcke
import 'dart:async';

import 'package:bloc/bloc.dart';
// import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:movie_app/common/constants/languages.dart';
import 'package:movie_app/domain/entities/language_entity.dart';

part 'language_event.dart';
part 'language_state.dart';

class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
  LanguageBloc() : super(LanguageLoaded(Locale(Languages.languages[0].code)));

  @override
  Stream<LanguageState> mapEventToState(
    LanguageEvent event,
  ) async* {
    if (event is ToggleLanguageEvent) {
      yield LanguageLoaded(Locale(event.language.code));
    }
  }
}

8.Erstellen Sie nun ein Ereignis

part of 'language_bloc.dart';

abstract class LanguageEvent {
  const LanguageEvent();
}

class ToggleLanguageEvent extends LanguageEvent {
  final LanguageEntity language;

  ToggleLanguageEvent(this.language);
}
  1. Erstellen Sie nun den Status
part of 'language_bloc.dart';

abstract class LanguageState {
  const LanguageState();

}

class LanguageLoaded extends LanguageState {
  final Locale locale;

  LanguageLoaded(this.locale);
}

10.Schaltfläche „Jetzt erstellen“, um die Sprache zu ändern.

RaisedButton(child: ,RaisedButton(child: Text('Switch', 
     onPressed: (int index) {
        BlocProvider.of<LanguageBloc>(context).add(
          ToggleLanguageEvent(
            Languages.languages[index], // index value can be 0 or 1 in our case
          ),                            // 0 - en, 1 - es
        );
        Navigator.of(context).pop();
      },
);

Bitte beachten Sie auch den Link für eine klare Implementierung
https://www.youtube.com/watch?v=W-2p3zB1z8k

AnasSafis Benutzeravatar
AnasSafi

Da die akzeptierte Antwort einige Mängel aufweist, werde ich eine neue festlegen:

Das Ändern des Gebietsschemas der App kann auf verschiedene Arten erfolgen. Hier zeige ich zwei Möglichkeiten:

Weg 1 (mit rxdart Und SharedPreferences Plugins):

Zum besseren Verständnis habe ich ein Projekt erstellt, um zu erklären, wie das geht. Sie finden es in https://github.com/AnasSafi/flutter_localization_example

Ausgabe des Projekts:

Geben Sie hier eine Bildbeschreibung ein


Weg 2:

Anmerkung 1: Ich wurde benutzt Gemeinsame Einstellungen Plugin zum Speichern des vom Client ausgewählten Gebietsschemas.

Hinweis 2: Ersetzen ar Und PS mit Ihrem Standardgebietsschema …

Vollständiger Code von main.dart Datei:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized(); //To solve problem (ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized)
  runApp(MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({Key? key}) : super(key: key);
  
  /*
  To Change Locale of App
   */
  static void setLocale(BuildContext context, Locale newLocale) async {
    _MainAppState? state = context.findAncestorStateOfType<_MainAppState>();

    var prefs = await SharedPreferences.getInstance();
    prefs.setString('languageCode', newLocale.languageCode);
    prefs.setString('countryCode', "");

    state?.setState(() {
      state._locale = newLocale;
    });
    
  }

  @override
  _MainAppState createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  Locale _locale = Locale('ar', 'ps');

  @override
  void initState() {
    super.initState();
    this._fetchLocale().then((locale) {
      setState(() {
        this._locale = locale;
      });
    });
  }


  /*
  To get local from SharedPreferences if exists
   */
  Future<Locale> _fetchLocale() async {
    var prefs = await SharedPreferences.getInstance();

    String languageCode = prefs.getString('languageCode') ?? 'ar';
    String countryCode = prefs.getString('countryCode') ?? 'ps';

    return Locale(languageCode, countryCode);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: _locale,
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        const FallbackCupertinoLocalisationsDelegate(),
      ],
      supportedLocales: [
        const Locale('en', ''), // English, no country code
        const Locale('ar', ''), // Arabic, no country code
      ],
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
      ),
      home: InitializeApp(), // here use your own home name...
    );
  }
}


/*
  To solve problem of hold press on inputs
 */
class FallbackCupertinoLocalisationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
  const FallbackCupertinoLocalisationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) =>
      DefaultCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
}

Von jeder anderen Klasse aus, in der Sie das Gebietsschema ändern müssen, können Sie meinen Weg verwenden:

Importieren main.dart Datei, dann verwenden Sie meinen einfachen DropdownButton:

Hinweis: ersetzen Wert: AppLocalizations.of(context)!.locale.toString(), In dieser Zeile erfahren Sie, wie Sie das aktuelle Gebietsschema der App abrufen können …

import 'package:yout_project_name/main.dart';

DropdownButton(
  onChanged: (v) => setState(() {
    MainApp.setLocale(context, Locale(v.toString(), ""));
  }),
  value: AppLocalizations.of(context)!.locale.toString(), // change this line with your way to get current locale to select it as default in dropdown
  items: [
    DropdownMenuItem(
      child: Text( 'English'), value: 'en'
    ),
    DropdownMenuItem(
      child: Text( 'العربية'), value: 'ar'
    ),
  ],
)

Wenn Sie einen Anbieter zur Statusverwaltung verwenden, können Sie diesem Artikel folgen.

https://medium.com/flutter-community/flutter-internationalization-the-easy-way-using-provider-and-json-c47caa4212b2

Schauen Sie sich das Paket language_builder in pub.dev an. Es ist sehr einfach zu verwenden. Indem Sie Ihr Root-Widget mit LanguageBuilder umschließen, können Sie die Sprache Ihrer App konfigurieren. Weisen Sie Ihre App an, die Sprache des Telefons zu verwenden, oder ändern Sie sie manuell in der App.

https://pub.dev/packages/lingual_builder

  • Fragen, die nach Ressourcen fragen, gehören nicht zum Thema. Diese Antwort bietet nur einen Link zu einer neuen Ressource und zeigt nicht, wie die Ressource implementiert werden kann, um die Frage im OP zu lösen. Obwohl dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verlinkte Seite ändert. – Aus der Rezension

    – Trenton McKinney

    28. September 2021 um 18:06 Uhr


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({Key? key}) : super(key: key);

  /*
  To Change Locale of App
   */
  static void setLocale(BuildContext context, Locale newLocale) async {
    _MainAppState? state = context.findAncestorStateOfType<_MainAppState>();

    var prefs = await SharedPreferences.getInstance();
    prefs.setString('languageCode', newLocale.languageCode);
    prefs.setString('countryCode', "");

    state?.setState(() {
      state._locale = newLocale;
    });
  }

  @override
  // ignore: library_private_types_in_public_api
  _MainAppState createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  Locale _locale = const Locale('ar', 'tn');

  @override
  void initState() {
    super.initState();
    _fetchLocale().then((locale) {
      setState(() {
        _locale = locale;
      });
    });
  }

  /*
  To get local from SharedPreferences if exists
   */
  Future<Locale> _fetchLocale() async {
    var prefs = await SharedPreferences.getInstance();

    String languageCode = prefs.getString('languageCode') ?? 'ar';
    String countryCode = prefs.getString('countryCode') ?? 'tn';

    return Locale(languageCode, countryCode);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: _locale,
      // ignore: prefer_const_literals_to_create_immutables
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        const FallbackCupertinoLocalisationsDelegate(),
      ],
      // ignore: prefer_const_literals_to_create_immutables
      supportedLocales: [
        const Locale('en', ''), // English, no country code
        const Locale('fr', ''),
        const Locale('ar', ''),
      ],
      theme: ThemeData(
        primarySwatch: Colors.deepPurple,
      ),
      home: const AppContent(), // here use your own home name...
    );
  }
}

/*
  To solve problem of hold press on inputs
 */
class FallbackCupertinoLocalisationsDelegate
    extends LocalizationsDelegate<CupertinoLocalizations> {
  const FallbackCupertinoLocalisationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) =>
      DefaultCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(FallbackCupertinoLocalisationsDelegate old) => false;
}

//___________________________________
class AppContent extends StatefulWidget {
  const AppContent({super.key});

  @override
  State<AppContent> createState() => _AppContentState();
}

class _AppContentState extends State<AppContent> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Text(AppLocalizations.of(context)!.hello),
            const SizedBox(height: 10),
            TextButton(
              onPressed: () {
                setState(() {
                  MainApp.setLocale(context, const Locale("fr", ""));
                });
              },
              child: const Text("Fr"),
            ),
            const SizedBox(height: 10),
            TextButton(
              onPressed: () {
                setState(() {
                  MainApp.setLocale(context, const Locale("en", ""));
                });
              },
              child: const Text("En"),
            ),
            const SizedBox(height: 10),
            TextButton(
              onPressed: () {
                setState(() {
                  MainApp.setLocale(context, const Locale("ar", ""));
                });
              },
              child: const Text("Ar"),
            ),
            const SizedBox(height: 10)
          ],
        ),
      ),
    );
  }
}

  • Fragen, die nach Ressourcen fragen, gehören nicht zum Thema. Diese Antwort bietet nur einen Link zu einer neuen Ressource und zeigt nicht, wie die Ressource implementiert werden kann, um die Frage im OP zu lösen. Obwohl dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verlinkte Seite ändert. – Aus der Rezension

    – Trenton McKinney

    28. September 2021 um 18:06 Uhr


1452830cookie-checkSchaltfläche zum Ändern der Sprache Flutter

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy