A package that helps eliminate boilerplate code when implementing translations in Flutter.
Add to pubspec.yaml:
dependencies:
flutter_translation: ^0.0.5
flutter_localizations:
sdk: flutter
Create the translator classes: app_translator.dart
abstract class AppTranslator extends ITranslator {
const AppTranslator();
String get title;
}
class PtTranslator extends AppTranslator {
String get title => 'Título';
}
class EnTranslator extends AppTranslator {
String get title => 'Title';
}
Create the AppLanguages class: app_languages.dart
class AppLanguages extends ILanguages {
AppLanguages.singleton();
@override
LanguageEntity get defaultLanguage =>
languages.firstWhere((lang) => lang.code == 'en');
@override
List<LanguageEntity> createLanguages() {
return [
LanguageEntity(
code: 'pt',
name: 'Português',
translator: PtTranslator(),
),
LanguageEntity(
code: 'en',
name: 'English',
translator: EnTranslator(),
),
];
}
}
You will need to create a singleton from AppLanguages. I'll use getIt to do that.
Getting started with get_it.
In you getIt setup:
getIt.registerSingleton<AppLanguages>(AppLanguages.singleton());
Create the localization, and the delegate classes: app_localizations.dart
class AppLocalizations extends ILocalizations<AppTranslator> {
AppLocalizations.singleton(Locale locale) : super(locale);
@override
AppTranslator getTranslator(String languageCode) {
throw UnimplementedError();
// something like: getIt<AppLanguages>().findByCode(languageCode).translator
}
}
class AppLocalizationsDelegate
extends ILocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();
@override
// here is where we need dependency injection
List<LanguageEntity> getLanguages() => throw UnimplementedError(); // something like: getIt<AppLanguages>().languages;
@override
Future<AppLocalizations> load(Locale locale) async {
return AppLocalizations.singleton(locale); // create AppLocalizations instance
}
}
Your setup is done!
Now you just need to start using it, like so:
import 'package:flutter_translation/flutter_translation.dart';
return MaterialApp(
supportedLocales: getIt<AppLanguages>()
.languages
.map((lang) => lang.toLocale()),
locale: getIt<AppLanguages>().defaultLanguage.toLocale(),
localizationsDelegates: [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
);
And then use to translate what you want:
final translator = getIt.get<AppTranslator>(param1: context);
return Scaffold(
body: Center(
child: Text(translator.title),
),
);
Note: I'm using getIt to deal with dependency injection, but you can use whatever you prefer to do this.
If you want to use getIt like me, add this to your getIt setup function:
getIt.registerFactoryParam<AppTranslator, BuildContext, Object>(
(context, nullParam) =>
Localizations.of(context, AppLocalizations).translator,
);
or simply
void findTranslator(BuildContext context){
return Localizations.of(context, AppLocalizations).translator;
}
Congratulations! You've added translation support to your app.
You can scale the languages and the strings as you need.
You can also manage the current language state to switch between languages.
If you found this implementation too big, remember that without this package it would be even bigger 😜. Don't forget to star if you liked 😉.