Локализация приложения на Flutter, используя пакет easy_localization

Локализация приложения на Flutter, используя пакет easy_localization

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

Read More