1. Введение
Краткое руководство со всем самым необходимым, которое позволит локализовать приложение на Flutter, используя пакет easy_localization.
Для демонстрации работы библиотеки используется стандартный демо-проект на Flutter. Данный демо-проект - это такой счетчик нажатий на кнопку, в котором присутствует лейбл "You have pushed the button this many times:". Ближайшая задача состоит в том, чтобы добавить еще один язык (русский) и добавить возможность переключать язык с английского на русский.
Для этого мы и воспользуемся пакетом easy_localization.
Текущая версия пакета ^3.0.1
- 🚀 Простые переводы на многие языки
- 🔌 Переводы в форматах JSON, CSV, Yaml, Xml
- 💾 Сохранение локали после изменения
- ⚡ Поддержка множественного числа
- ↩️ Перенаправление при отсутствии ключа
- ⁉️ Error виджет для отсутствующих переводов
- ❤️ Метода расширения на
Text
иBuildContext
- 💻 Генерация кода
- 🛡️ Null safety
- 🖨️ Логгер
2. Установка
Для добавления пакета в проект необходимо воспользоваться командой:
flutter pub add easy_localization
Либо добавить в файл pubspec.yaml в секцию dependencies следующую строку:
easy_localization: ^3.0.1
Вместо ^3.0.1 указывается последняя версия.
3. Добавление переводов
Необходимо создать директорию, в которой будут находиться файлы с переводами.
Для этого в корне создаем папку assets
и в ней еще одну папку translations
.
После этого в данную директорию необходимо добавить файлы с переводами.
Название файлов может иметь вид: {languageCode}.{ext}
либо {languageCode}-{countryCode}.{ext}
assets/translations создадим 2 файла:
1) en.json
{
"you_have_pushed_the_button_this_many_times": "You have pushed the button this many times:"
}
2) ru.json
{
"you_have_pushed_the_button_this_many_times": "Количество раз, которое вы нажали на кнопку:"
}
Соответственно, по ключу "you_have_pushed_the_button_this_many_times"
.
Есть возможность получить две разные строки в зависимости от выбранной локализации:
1) "You have pushed the button this many times: "
2) "Количество раз, которое вы нажали на кнопку: "
После этого в pubspec.yaml
файл необходимо добавить следующий фрагмент кода:
assets:
- assets/translations/
4. Конфигурация
Для работы пакета easy_localization под IOS необходимо перейти по пути ios/Runner/Info.plist
и добавить следующий фрагмент кода:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>ru</string>
</array>
В массиве перечисляются поддерживаемые языки. В данном случае английский и русский.
Далее в начале функции main()
необходимо добавить:
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
Обернуть MyApp
виджет в виджет EasyLocalization
и установить необходимые свойства:
runApp(
EasyLocalization(
supportedLocales: [Locale('en'), Locale('de')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
child: MyApp()
),
);
supportedLocales - поддерживаемые языки (английский и русский);
path - путь до файлов с переводами (en.json и ru.json);
fallbackLocale - при отсутствии значения по ключу будет использоваться значение указанного языка.
Далее в виджете MaterialApp
необходимо установить значения в следующие свойства:
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
5. Генерация кода
Теперь необходимо сгенерировать несколько файлов. Для этого используется команда flutter pub run easy_localization:generate
.
В первом случае ее необходимо запустить с аргументом --source-dir
или кратко -S
flutter pub run easy_localization:generate -S "assets/translations"
Во втором случае команда запускается с аргументами --format (-f)
--output-file (-o)
--source-dir (-S)
flutter pub run easy_localization:generate -f keys -o locale_keys.g.dart -S "assets/translations"
"assets/translations"
- путь до файлов с переводами.
После запуска команд получаем 2 файла:
1) codegen_loader.g.dart - файл содержит класс CodegenLoader
, в котором находятся статические словари с переводами:
import 'dart:ui';
import 'package:easy_localization/easy_localization.dart' show AssetLoader;
class CodegenLoader extends AssetLoader{
const CodegenLoader();
@override
Future<Map<String, dynamic>> load(String fullPath, Locale locale ) {
return Future.value(mapLocales[locale.toString()]);
}
static const Map<String,dynamic> en = {
"you_have_pushed_the_button_this_many_times": "You have pushed the button this many times:"
};
static const Map<String,dynamic> ru = {
"you_have_pushed_the_button_this_many_times": "Количество раз, которое вы нажали на кнопку:"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"en": en, "ru": ru};
}
2) locale_keys.g.dart - содержит класс LocaleKeys
с набором констант ключей:
abstract class LocaleKeys {
static const you_have_pushed_the_button_this_many_times = 'you_have_pushed_the_button_this_many_times';
}
После генерации файлов необходимо добавить строчку assetLoader: CodegenLoader(),
в виджет EasyLocalization assetLoader
.
На данный момент он выгладит следующим образом:
EasyLocalization(
supportedLocales: [Locale('en'), Locale('ru')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
assetLoader: CodegenLoader(),
child: MyApp(),
),
6. Изменение языка
Для изменения языка используется метод context.setLocale()
. В него необходимо передать локализацию, которую вы хотите установить, например Locale('ru)
.
Добавим кнопку в свойство leading
виджета AppBar
leading: IconButton(
icon: Icon(Icons.language),
onPressed: () {
if (context.locale == Locale('ru')) {
context.setLocale(Locale('en'));
} else {
context.setLocale(Locale('ru'));
}
},
),
При нажатии на кнопку локализация будет меняться. В случае, если текущий язык русский, язык изменится на английский. И наоборот, если язык английский, то язык изменится на русский.
Полезные ссылки
Телеграм: https://t.me/the_cybermania
Исходный код: https://github.com/AlexeyShpavda/easy_localization
Видео: https://www.youtube.com/watch?v=GLR2TW64V6A