Шеринг файлов локализации между несколькими пакетами в Flutter
Когда вы разрабатываете большое приложение, вы волей-неволей дробите его на пакеты, однако если использовать стандартный механизм, который предлагают разработчики Flutter в официальной документации, прямого способа пошерить файлы локализации между проектами нет.
Есть вариант заново настроить flutter_localizations
в новом пакете и заполнять там новые переводы и переносить старые. Но это сложно и кажется неправильным.
Тогда я предлагаю второй вариант. Поделиться переводами из одного пакета в другой. В этой статье я расскажу, как это сделать.
Идея
Пакет flutter_localizations
по умолчанию генерирует файлы в папку /.dart_tool/flutter_gen/gen_l10n
, но это директорию нельзя пошерить другим пакетам.
Наша задача создать пакет локализации и с помощью файла экспорта экспортировать файл app_localizations.dart
из /.dart_tool/flutter_gen/gen_l10n/
, чтобы его могли заиспользовать другие пакеты, в том числе наш основной.
Реализация
Создам пакет под названием sputnik_localization
и добавлю туда плагины intl
и app_localizations
:
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any
В проекте:
MaterialApp(
...
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'),
],
...
)
Затем создам папку lib/l10n/generated
. В папке lib/l10n
создам сам файл для локализации app_en.arb
. Заполню его информацией:
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "The conventional newborn programmer greeting"
},
"alreadyHaveAccount": "Already have account?",
"signIn": "Sign in",
"signUp": "Sign up",
"invalidEmail": "Incorrect e-mail format",
"invalidPassword": "The password must contain no less than 6 and no more than 64 characters",
"passwordDontMatch": "The passwords don't match",
"unknownSignUpError": "Unknown error when creating an account",
"unknownSignInError": "Unknown error when logging in to the account"
}
Дальше необходимо в корне проекта создать файл l10n.yaml
со следующим содержимым:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-dir: lib/l10n/generated
synthetic-package: false
nullable-getter: false
arb-dir
— расположение файлов локализации (в нашем случае app_en.arb
)template-arb-file
— основной arb-файлoutput-localization-file
— файл, куда будет сгенерирована локализацияoutput-dir
— папка, в которую будет идти генерация.synthetic-package
— флаг, который отвечает за выбор по умолчанию директории локализации (если false, то значение будет браться из arb-dir
)nullable-getter
— позволяет не проверять на null значение перевода каждый раз при использовании, например, если значение true — AppLocalizations.of(context).alreadyHaveAccount ?? "Значение если перевода нет"
.
Дальше переходим в файл экспорта, в моем случае он называется lib/sputnik_localization.dart
, в вашем случае это lib/<название_пакета>.dart
. Там у меня лежит такой код:
library sputnik_localization;
export 'package:flutter_localizations/flutter_localizations.dart'; // пакет
export 'l10n/generated/app_localizations.dart'; // переводы
export 'src/utils.dart'; // мои дополнительные приколюхи
Все! Теперь можно использовать в вашем проекте:
В pubspec.yaml
подключаете:
sputnik_localization:
path: packages/sputnik_localization
В проекте:
import 'package:sputnik_localization/sputnik_localization.dart';
...
AppLocalizations.of(context).helloWorld
Готово!
Дополнение
Чтобы проще было пользоваться плагином локализации, вы можете написать дополнение в пакет локализации, как у меня файл utils.dart
.
import 'package:flutter/material.dart';
import 'package:sputnik_localization/l10n/generated/app_localizations.dart';
extension BuildContextLocalizationEx on BuildContext {
AppLocalizations get tr =>; AppLocalizations.of(this);
}
Заключение
Таким образом вы можете дробить свой проект на множество пакетов и не терять файлы локализации, не запариваться над синхронизацией нескольких файлов. Применяйте на здоровье!
Хорошего настроения и добра <3!