Maîtriser le flutter : prise en charge multilingue

Une chose que Flutter ne vous permet pas de faire immédiatement est la prise en charge multilingue . Il y a plusieurs façons de contourner ce problème, aujourd'hui nous allons voir l'un d'entre eux. Ce n'est pas difficile, mais cela vous donne un bon contrôle sur votre sortie.

1. Ajouts de fichiers Yaml

Tout d'abord, nous devrons ajouter quelques lignes à notre fichier .yaml. Nous devrons ajouter deux packages, le package intl et flutter_localisations :

dependencies:
  flutter:
    sdk: flutter
#This lines are new
  flutter_localizations:
    sdk: flutter
cupertino_icons: ^1.0.0
  
  #This line is new
  intl: ^0.17.0

Les deux parties les plus importantes de notre configuration sont les localisationsDelegates et la localeResolutionCallback , vérifions la première. Ce LocalizationsDelegatessont des classes qui définissent une série de valeurs localisées en les chargeant. Sur notre classe principale, en tant que paramètres pour la MaterialApp, nous devons définir nos délégués :

localizationsDelegates: [
        AppLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],

abstract class Languages {
static Languages of(BuildContext context) {
    return Localizations.of<Languages>(context, Languages);
  }
}
class AppLocalizationsDelegate extends LocalizationsDelegate<Languages> {
const AppLocalizationsDelegate();
@override
  bool isSupported(Locale locale) =>
      ['es', 'en', 'de', 'it'].contains(locale.languageCode);
@override
  Future<Languages> load(Locale locale) => _load(locale);
static Future<Languages> _load(Locale locale) async {
    switch (locale.languageCode) {
      case 'it':
        return LanguageIt();
      case 'es':
        return LanguageEs();
      case 'de':
        return LanguageDe();
      case 'en':
        return LanguageEn();
      default:
        return LanguageEn();
    }
  }
@override
  bool shouldReload(LocalizationsDelegate<Languages> old) => false;
}

abstract class Languages {
static Languages of(BuildContext context) {
    return Localizations.of<Languages>(context, Languages);
  }
String get aString;
}

class LanguageIt extends Languages {
@override
  String get aString => "Sono un testo";
}
class LanguageEs extends Languages {
@override
  String get aString => "Soy un texto";
}
class LanguageEn extends Languages {
@override
  String get aString => "I am a text";
}
class LanguageDe extends Languages {
@override
  String get aString => "Ich bin ein Text";
}

supportedLocales: [
        const Locale('it', ''),
        const Locale('en', ''),
        const Locale('de', ''),
        const Locale('es', '')
      ],
localeResolutionCallback: (locale, supportedLocales) {
        for (var supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale?.languageCode) {
            return supportedLocale;
          }
        }
        return supportedLocales.first;
      },

Languages.of(context).aString

  • « Io sono un testo » pour la langue italienne
  • « Ich bin ein Text » pour la langue allemande
  • "Soy un texto " pour la langue espagnole
  • "Je suis un texte " pour la langue anglaise ou une langue non prise en charge.

3. Allumez où que vous soyez

Pour atteindre notre prochain objectif, nous devrons ajouter un package de gestion d'état , j'ai choisi Provider car, à mon avis, il est assez facile à mettre en œuvre et à comprendre. Nous devrons créer un ChangeNotifierqui contiendra la locale actuelle et l'initialiser en tant que système :

class LocalizationManager extends ChangeNotifier {
  static Locale get defaultLocale => Locale('it', 'IT');
Locale _currentLocale;
final locales = [
    const Locale('it', ''),
    const Locale('en', ''),
    const Locale('de', ''),
    const Locale('es', '')
  ];

Future<Locale> locale(BuildContext context) async {
    if (_currentLocale != null) {
      return _currentLocale;
    }
    String platformLocaleName = Platform.localeName;
    if (platformLocaleName.contains('_')) {
      platformLocaleName = platformLocaleName.split('_').first;
    }
    if (platformLocaleName.contains('-')) {
      platformLocaleName = platformLocaleName.split('-').first;
    }
    if (platformLocaleName != null) {
      for (Locale configurationLocale in locales) {
        if (platformLocaleName.toLowerCase() ==
            configurationLocale.languageCode.toLowerCase()) {
          _currentLocale = configurationLocale;
          break;
        }
      }
    }
    if (_currentLocale == null) {
      _currentLocale = locales.first ?? defaultLocale;
    }
    return _currentLocale;
  }
Future<void> setLocale(Locale locale) async {
    _currentLocale = locale;
    notifyListeners();
  }
}

Future<void> setLocale(Locale locale) async {
    _currentLocale = locale;
    notifyListeners();
  }

MultiProvider(
      providers:[
        ChangeNotifierProvider<LocalizationManager>(create: (_) => LocalizationManager()),
      ],
      child: Consumer<LocalizationManager>(
        builder: (context, localizationManager, child) {
          return FutureBuilder<Locale>(
            future: localizationManager.locale(context),
            builder: (context, snapshot) {
              return MaterialApp(
                localizationsDelegates: [
                  AppLocalizationsDelegate(),
                  GlobalMaterialLocalizations.delegate,
                  GlobalWidgetsLocalizations.delegate,
                  GlobalCupertinoLocalizations.delegate,
                ],
                supportedLocales: [
                  const Locale('it', ''),
                  const Locale('en', ''),
                  const Locale('de', ''),
                  const Locale('es', '')
                ],
                locale: snapshot.data,
                localeResolutionCallback: (locale, supportedLocales) {
                  return locale;
                },
                home: Scaffold(
                  backgroundColor: Colors.black,
                  body: DemoApp(),
                ),
              );
            },
          );
        },
      ),
    ),

CupertinoButton(
              child: Text('Ita'),
              onPressed: () {
                Provider.of<LocalizationManager>(context, listen: false).setLocale(Locale('it', ''));
              },
            ),
            CupertinoButton(
              child: Text('En'),
              onPressed: () {
                Provider.of<LocalizationManager>(context, listen: false).setLocale(Locale('en', ''));
              },
            ),
            CupertinoButton(
              child: Text('Es'),
              onPressed: () {
                Provider.of<LocalizationManager>(context, listen: false).setLocale(Locale('es', ''));
              },
            ),
            CupertinoButton(
              child: Text('De'),
              onPressed: () {
                Provider.of<LocalizationManager>(context, listen: false).setLocale(Locale('de', ''));
              },
            ),

Il s'agit d'une implémentation assez simple, nous pouvons également ajouter la locale en tant que préférence partagée afin qu'elle soit enregistrée et que le changement de langue puisse être permanent, mais je vous laisse toute autre implémentation dont vous avez besoin. Bon travail, nous l'avons fait aussi aujourd'hui!

Suggested posts

Maîtriser le développement mobile : comment choisir le meilleur langage de programmation pour votre application

Maîtriser le développement mobile&nbsp;: comment choisir le meilleur langage de programmation pour votre application

Le développement mobile est devenu un élément essentiel pour que les entreprises réussissent dans le monde numérique d'aujourd'hui. En tant que développeur d'applications mobiles, il est essentiel de choisir le bon langage de programmation pour créer votre application.

Un guide du débutant pour détester le monde [001] — Égalité

Un guide du débutant pour détester le monde [001] — Égalité

Avis de non-responsabilité : L'« essai » suivant reflète une opinion et une vision du monde étonnamment subjectives. Le lecteur est invité à s'engager de manière critique avec moi, mais cela fait partie de ma philosophie de ne pas se soucier des opinions des autres.

Related posts

Rassembler OSINT pour la chasse aux menaces

Rassembler OSINT pour la chasse aux menaces

Salut les cyber-amateurs ! Bienvenue à nouveau dans la série OSINT pour la chasse aux menaces. Dans le premier article, je vous ai donné un aperçu d'OSINT et de son importance dans la chasse aux menaces.

Le mensonge du cow-boy

Comment les mégacorporations ont vendu aux Américains un mensonge costaud

Le mensonge du cow-boy

C'est un matin brillamment doré dans les collines de l'ouest, alors que les premiers rayons du soleil illuminent l'herbe givrée des plaines. Un troupeau de bovins Angus placides, d'un noir de jais et massif, se découpe sur le lever du soleil alors qu'ils descendent un sentier battu vers un lieu qu'ils connaissent tous bien; le bar du petit-déjeuner.

Le premier livre d'un enfant sur la défonce

Le premier livre d'un enfant sur la défonce

(Attention - Ceci est une satire, destinée à être joyeusement subversive - Certainement pas pour les enfants) Vous avez vu votre mère et votre père se cacher dans la cuisine et fumer ces cigarettes malodorantes. Ils vous disent.

Le meurtre de Jordan Neely et le problème du racisme « patriotique »

Les États-Unis peuvent-ils prendre la mesure essentielle de ne pas assimiler un comportement raciste au fait d'être un bon Américain ?

Le meurtre de Jordan Neely et le problème du racisme « patriotique »

[Alerte de déclenchement : cet essai comprend des captures d'écran de personnes faisant l'éloge du meurtrier de Jordan Neely.] Les responsables de l'application des lois ont finalement - et peut-être à contrecœur - inculpé Daniel Penny, l'homme qui a étouffé Jordan Neely jusqu'à sa mort, pour cet homicide.