FlutterMiddleSystem design

Как обрабатывать локализацию (internationalization) приложения во Flutter?

Официальный путь — flutter_localizations + ARB-файлы + кодогенерация (l10n.yaml, generate: true). Строки доступны через AppLocalizations.of(context) с поддержкой плюральных форм ICU.

Локализация Flutter-приложения

Flutter поставляет официальный пакет flutter_localizations и инструмент кодогенерации на основе ARB-файлов (flutter_gen / intl). Это рекомендованный подход начиная с Flutter 2.0.

Шаг 1 — Зависимости

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.19.0

flutter:
  generate: true  # включает кодогенерацию l10n

Шаг 2 — Конфигурация l10n.yaml

Создайте файл l10n.yaml в корне проекта:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
nullable-getter: false

Шаг 3 — ARB-файлы

ARB (Application Resource Bundle) — JSON-формат для строк локализации.

lib/l10n/app_en.arb:

{
  "@@locale": "en",
  "appTitle": "Talento Jobs",
  "@appTitle": { "description": "Application title" },
  "jobsFound": "{count, plural, =0{No jobs} =1{1 job} other{{count} jobs}}",
  "@jobsFound": {
    "description": "Number of jobs found",
    "placeholders": {
      "count": { "type": "int" }
    }
  }
}

lib/l10n/app_ru.arb:

{
  "@@locale": "ru",
  "appTitle": "Talento Вакансии",
  "jobsFound": "{count, plural, =0{Нет вакансий} =1{1 вакансия} few{{count} вакансии} many{{count} вакансий} other{{count} вакансий}}"
}

Шаг 4 — Подключение к MaterialApp

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

MaterialApp(
  localizationsDelegates: const [
    AppLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: AppLocalizations.supportedLocales,
  // необязательно: фиксированная локаль для тестов
  // locale: const Locale('ru'),
  home: const HomePage(),
);

Шаг 5 — Использование строк

// в любом виджете
Text(AppLocalizations.of(context)!.appTitle)
Text(AppLocalizations.of(context)!.jobsFound(42))

// Dart 3 / Flutter 3.7+: extension для краткости
extension AppLocalizationsX on BuildContext {
  AppLocalizations get l10n => AppLocalizations.of(this)!;
}
// применение:
Text(context.l10n.appTitle)

Кодогенерация

flutter gen-l10n
# или автоматически при сборке:
flutter run

Генерируемые файлы появятся в .dart_tool/flutter_gen/gen_l10n/. Добавьте эту папку в .gitignore.

Смена локали во время работы

// с помощью state management (например, Riverpod)
final localeProvider = StateProvider<Locale>((ref) => const Locale('en'));

// в MaterialApp
MaterialApp(
  locale: ref.watch(localeProvider),
  // ...
)

// смена локали
ref.read(localeProvider.notifier).state = const Locale('ru');

Подводные камни

  • Забытый generate: true в pubspec.yaml — без этого флага flutter gen-l10n не создаёт файлы автоматически при сборке, и импорт flutter_gen не найдёт пакет.
  • Plural-формы для русского языка требуют категорий few, many, other (ICU plural rules); если написать только =1{...} other{...}, числа 2–4, 11–14 отобразятся неверно.
  • Отсутствие ключа в одном из ARB-файлов не приводит к ошибке сборки — Flutter молча вернёт ключ из шаблонного locale, что маскирует незавершённый перевод.
  • context недоступен без BuildContext — нельзя получить локализованные строки вне дерева виджетов (например, в модели). Используйте callback или передавайте строки явно.
  • GlobalCupertinoLocalizations.delegate нужен при использовании CupertinoApp или Cupertino-виджетов; без него дата-пикеры будут отображаться на английском независимо от выбранной локали.
  • Числовое форматирование не автоматическое — для формата денег, процентов и дат используйте NumberFormat и DateFormat из пакета intl явно, передавая текущую локаль.
  • Кэш локали устройстваLocalizations.localeOf(context) может вернуть не тот locale сразу после смены, пока дерево не перестроилось. Используйте WidgetsBinding.instance.platformDispatcher.locale для проверки за пределами дерева.

Common mistakes

  • Сводить «обрабатывать локализацию (internationalization) приложения во Flutter» к синтаксису и не объяснять render tree.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-22.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

What the interviewer is testing

  • Формулирует точную модель для «обрабатывать локализацию (internationalization) приложения во Flutter» и подтверждает ее корректным примером.
  • Умеет связать ответ с frame scheduling, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-22, включая производительность, память и сопровождение.

Sources

Related topics