Vous avez besoin que votre application Flutter soit disponible en plusieurs langues mais vous ne savez pas comment vous y prendre ?
Ne vous inquiétez pas, EL TIGRE vous propose une solution simple et efficace !
Au préalable
- Avoir installé Flutter
- Avoir des notions de base de Dart et Flutter
Mettre en place son application pour supporter plusieurs langues
L’application que nous allons faire est très simple. Elle affichera simplement un texte à l’écran et nous allons changer la langue du téléphone. Nous allons alors voir en temps réel l’application se mettre à jour.
Cette solution se basera sur la librairie « flutter_localizations » native à flutter. Il faudra tout de même la spécifier dans notre fichier pubspec.yaml afin de pouvoir l’utiliser.
name: flutter_multilingues description: Miltilingues application. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true
Pour commencer nous allons créer le fichier app_local.dart. Celui-ci comportera la classe qui regroupe tous les champs textes qui devront être traduits.
import 'package:meta/meta.dart'; class HomeLocal { String question; String ctaYes; String ctaNo; HomeLocal({ @required this.question, @required this.ctaYes, @required this.ctaNo, }); } abstract class AppLocal { HomeLocal get home; }
AppLocal est une classe abstraite qui déclare un get du type HomeLocal. La classe HomeLocal définie tous les champs nécessaires au widget Home que nous allons créer plus tard.
Maintenant nous pouvons créer un dossier lib/locales qui contiendra deux fichiers : fr.dart et en.dart
lib/locales/fr.dart
import 'package:flutter_multilingues/app_locale.dart'; class FrLocal extends AppLocal { @override HomeLocal get home => HomeLocal( question: 'Aimez vous cette application ?', ctaYes: 'Oui', ctaNo: 'Non', ); }
lib/locales/en.dart
import 'package:flutter_multilingues/app_locale.dart'; class EnLocal extends AppLocal { @override HomeLocal get home => HomeLocal( question: 'Do you like this application ?', ctaYes: 'Yes', ctaNo: 'No', ); }
Nous pouvons voir que les deux classes FrLocal et EnLocal étendent la classe abstraite AppLocal. Il est donc nécessaire d’implémenter les surcouches de celles-ci.
Ici notre fameuse fonction get « home » qui retourne une instanciation de HomeLocal.
Créez maintenant un fichier lib/app_localizations.dart
import 'package:flutter/material.dart'; import 'package:flutter_multilingues/app_locale.dart'; import 'package:flutter_multilingues/locales/en.dart'; import 'package:flutter_multilingues/locales/fr.dart'; class AppLocalizations { final Locale locale; Map<String, AppLocal> _localizedValues = { 'fr': FrLocal(), 'en': EnLocal(), }; AppLocalizations(this.locale); static AppLocalizations of(BuildContext context) => Localizations.of<AppLocalizations>(context, AppLocalizations); AppLocal get lang => _localizedValues[locale.languageCode]; }
Nous créons ici :
- Une classe AppLocalizations où l’on définit _localizedValues comme étant un Map ayant ses clés du type String et ses valeurs du type AppLocal.
- La fonction get « lang » qui renvoie l’AppLocal en fonction de la clé du paramètre du type Local passé à la construction de la classe AppLocalizations
- Et une fonction « of » qui permet de récupérer le widget du type AppLocalizations le plus proche du contexte avec lequel la fonction est appelée.
Ajoutons-y la classe AppLocalizationsDelegate qui étant LocalizationsDelegate<AppLocalizations>
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> { const AppLocalizationsDelegate(); @override bool isSupported(Locale locale) => true; @override Future<AppLocalizations> load(Locale locale) => SynchronousFuture<AppLocalizations>(AppLocalizations(locale)); @override bool shouldReload(AppLocalizationsDelegate old) => false; }
N’oubliez pas d’importer :
import 'package:flutter/foundation.dart' show SynchronousFuture;
Cette classe est nécessaire lors de la création du widget MaterialApp afin de gérer les langues.
Créez maintenant le fichier lib/multilingues.dart qui définira le widget père de l’application
import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_multilingues/app_localizations.dart'; import './screens/home.dart'; class Multilingues extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Multilingues', localizationsDelegates: [ const AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: [ const Locale('fr', ''), const Locale('en', ''), ], home: Home(), ); } }
Précisez bien les langues supportées avec le paramètre « supportedLocales » et les langues déléguées. Pour plus d’informations, référez-vous à la documentation officielle.
Enfin, créez le fichier lib/screens/home.dart
import 'package:flutter/material.dart'; import 'package:flutter_multilingues/app_locale.dart'; import '../app_localizations.dart'; class Home extends StatelessWidget { @override Widget build(BuildContext context) { AppLocal _local = AppLocalizations.of(context).lang; return Scaffold( body: Center( child: Text(_local.home.question), ), ); } }
Ici on récupère les données grâce à la fonction static « of » de notre classe AppLocal et nous les affichons.
Lancez l’application et vous devriez voir la question en français si votre téléphone est en français.
Comportement
Avec cette solution le comportement est naturel.
- Si vous n’avez qu’une seule langue définie
- Si elle est supportée par l’application, celle-ci sera utilisée.
- Si elle n’est pas supportée, la première langue définie dans le tableau « supportedLocales » sera utilisée.
- Si vous avez plusieurs langues définies
- Si qu’une seule langue est supportée par l’application, celles-ci sera utilisée.
- Si plusieurs langues sont supportées par l’application, elle utilisera la première langue supportée et classée la plus haute dans vos préférences.
- Si aucunes n’est supportée, la première langue définie dans le tableau « supportedLocales » sera utilisée.