Ответ
В своих Flutter-проектах я использовал несколько подходов к локализации:
1. Стандартный подход с flutter_localizations и intl (рекомендуемый):
# pubspec.yaml
dependencies:
flutter_localizations:
sdk: flutter
intl: ^0.18.0
flutter:
generate: true
// main.dart
return MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate, // Сгенерированный делегат
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
locale: Locale('ru', 'RU'), // Текущая локаль
home: HomePage(),
);
Структура файлов .arb:
// lib/l10n/app_en.arb
{
"@hello": {
"description": "Приветствие"
},
"hello": "Hello {name}",
"@itemsCount": {
"description": "Количество элементов",
"placeholders": {
"count": {}
}
},
"itemsCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"
}
// lib/l10n/app_ru.arb
{
"hello": "Привет, {name}",
"itemsCount": "{count, plural, =0{Нет элементов} =1{1 элемент} few{{count} элемента} other{{count} элементов}}"
}
Использование в коде:
Text(AppLocalizations.of(context)!.hello('Анна')),
Text(AppLocalizations.of(context)!.itemsCount(5)),
2. Динамическое переключение локали через State Management:
// С использованием Provider/Riverpod
class LocaleController {
Locale _locale = Locale('en');
Future<void> setLocale(Locale locale) async {
_locale = locale;
await _saveToPrefs(locale);
notifyListeners();
}
Locale get locale => _locale;
}
// В MaterialApp
locale: context.watch<LocaleController>().locale,
3. Для более простых проектов — кастомное решение:
class AppLocalizations {
final Map<String, Map<String, String>> _localizedValues = {
'en': {
'welcome': 'Welcome',
'settings': 'Settings',
},
'ru': {
'welcome': 'Добро пожаловать',
'settings': 'Настройки',
},
};
String translate(String key, BuildContext context) {
final locale = Localizations.localeOf(context).languageCode;
return _localizedValues[locale]?[key] ?? _localizedValues['en']![key]!;
}
}
4. Пакеты для специфических нужд:
easy_localization— для быстрого старта с JSON/YAML файламиflutter_i18n— поддержка вложенных ключей и плюрализацииintl_utils— дополнительные утилиты для работы сintl
В production-проектах я предпочитаю стандартный подход с intl, так как он обеспечивает типобезопасность, поддержку плюрализации, гендера и форматирования дат/чисел из коробки. Для динамической смены языка без перезапуска приложения комбинирую его с провайдером для управления состоянием локали.