本地化
简介
本地化允许您以多种语言提供应用。Nylo Website v7 使用 JSON 语言文件简化了文本本地化。
以下是一个简单示例:
lang/en.json
{
"welcome": "Welcome",
"greeting": "Hello {{name}}"
}
在您的组件中:
Text("welcome".tr()) // "Welcome"
Text("greeting".tr(arguments: {"name": "Anthony"})) // "Hello Anthony"
配置
本地化在 lib/config/localization.dart 中配置:
final class LocalizationConfig {
// Default language code (matches your JSON file, e.g., 'en' for lang/en.json)
static final String languageCode =
getEnv('DEFAULT_LOCALE', defaultValue: "en");
// LocaleType.device - Use device's language setting
// LocaleType.asDefined - Use languageCode above
static final LocaleType localeType =
getEnv('LOCALE_TYPE', defaultValue: 'asDefined') == 'device'
? LocaleType.device
: LocaleType.asDefined;
// Directory containing language JSON files
static const String assetsDirectory = 'lang/';
// List of supported locales
static const List<Locale> supportedLocales = [
Locale('en'),
Locale('es'),
// Add more locales as needed
];
// Fallback when a key is not found in the active locale
static const String fallbackLanguageCode = 'en';
// RTL language codes
static const List<String> rtlLanguages = ['ar', 'he', 'fa', 'ur'];
// Log warnings for missing translation keys
static final bool debugMissingKeys =
getEnv('DEBUG_TRANSLATIONS', defaultValue: 'false') == 'true';
}
添加本地化文件
将语言 JSON 文件添加到 lang/ 目录:
lang/
├── en.json # English
├── es.json # Spanish
├── fr.json # French
└── ...
lang/en.json
{
"welcome": "Welcome",
"settings": "Settings",
"navigation": {
"home": "Home",
"profile": "Profile"
}
}
lang/es.json
{
"welcome": "Bienvenido",
"settings": "Configuración",
"navigation": {
"home": "Inicio",
"profile": "Perfil"
}
}
在 pubspec.yaml 中注册
确保您的语言文件包含在 pubspec.yaml 中:
flutter:
assets:
- lang/
文本本地化
使用 .tr() 扩展或 trans() 辅助函数来翻译字符串:
// Using the .tr() extension
"welcome".tr()
// Using the trans() helper
trans("welcome")
嵌套键
使用点符号访问嵌套的 JSON 键:
lang/en.json
{
"navigation": {
"home": "Home",
"profile": "Profile"
}
}
"navigation.home".tr() // "Home"
trans("navigation.profile") // "Profile"
参数
使用 {{key}} 语法将动态值传递到翻译中:
lang/en.json
{
"greeting": "Hello {{name}}",
"items_count": "You have {{count}} items"
}
"greeting".tr(arguments: {"name": "Anthony"})
// "Hello Anthony"
trans("items_count", arguments: {"count": "5"})
// "You have 5 items"
更新区域设置
在运行时更改应用的语言:
// Using NyLocalization directly
await NyLocalization.instance.setLanguage(
context,
language: 'es' // Must match your JSON filename (es.json)
);
如果您的组件继承 NyPage,请使用 changeLanguage 辅助函数:
class _SettingsPageState extends NyPage<SettingsPage> {
@override
Widget view(BuildContext context) {
return ListView(
children: [
ListTile(
title: Text("English"),
onTap: () => changeLanguage('en'),
),
ListTile(
title: Text("Español"),
onTap: () => changeLanguage('es'),
),
],
);
}
}
设置默认区域设置
在您的 .env 文件中设置默认语言:
DEFAULT_LOCALE="en"
或者通过设置以下内容使用设备的区域设置:
LOCALE_TYPE="device"
更改 .env 后,重新生成环境配置:
metro make:env --force
支持的区域设置
在 LocalizationConfig 中定义您的应用支持的区域设置:
static const List<Locale> supportedLocales = [
Locale('en'),
Locale('es'),
Locale('fr'),
Locale('de'),
Locale('ar'),
];
此列表由 Flutter 的 MaterialApp.supportedLocales 使用。
备用语言
当在当前区域中找不到翻译键时,Nylo Website 会回退到指定的语言:
static const String fallbackLanguageCode = 'en';
这确保您的应用在翻译缺失时永远不会显示原始键。
RTL 支持
Nylo Website v7 包含对从右到左(RTL)语言的内置支持:
static const List<String> rtlLanguages = ['ar', 'he', 'fa', 'ur'];
// Check if current language is RTL
if (LocalizationConfig.isRtl(currentLanguageCode)) {
// Handle RTL layout
}
调试缺失键
在开发期间启用缺失翻译键的警告:
在您的 .env 文件中:
DEBUG_TRANSLATIONS="true"
当 .tr() 找不到键时会记录警告,帮助您捕获未翻译的字符串。
NyLocalization API
NyLocalization 是管理所有本地化的单例。除了基本的 translate() 方法外,它还提供了几个额外的方法:
检查翻译是否存在
bool exists = NyLocalization.instance.hasTranslation('welcome');
// true if the key exists in the current language file
// Also works with nested keys
bool nestedExists = NyLocalization.instance.hasTranslation('navigation.home');
获取所有翻译键
对于调试以查看加载了哪些键很有用:
List<String> keys = NyLocalization.instance.getAllKeys();
// ['welcome', 'settings', 'navigation', ...]
不重启更改区域设置
如果您想静默更改区域设置(不重启应用):
await NyLocalization.instance.setLocale(locale: Locale('fr'));
这会加载新的语言文件但不会重启应用。当您想手动处理 UI 更新时很有用。
检查 RTL 方向
bool isRtl = NyLocalization.instance.isDirectionRTL(context);
访问当前区域设置
// Get the current language code
String code = NyLocalization.instance.languageCode; // e.g., 'en'
// Get the current Locale object
Locale currentLocale = NyLocalization.instance.locale;
// Get Flutter localization delegates (used in MaterialApp)
var delegates = NyLocalization.instance.delegates;
完整 API 参考
| 方法/属性 | 返回值 | 描述 |
|---|---|---|
instance |
NyLocalization |
单例实例 |
translate(key, [arguments]) |
String |
翻译键,可选参数 |
hasTranslation(key) |
bool |
检查翻译键是否存在 |
getAllKeys() |
List<String> |
获取所有已加载的翻译键 |
setLanguage(context, {language, restart}) |
Future<void> |
更改语言,可选重启 |
setLocale({locale}) |
Future<void> |
不重启更改区域设置 |
setDebugMissingKeys(enabled) |
void |
启用/禁用缺失键日志 |
isDirectionRTL(context) |
bool |
检查当前方向是否为 RTL |
restart(context) |
void |
重启应用 |
languageCode |
String |
当前语言代码 |
locale |
Locale |
当前 Locale 对象 |
delegates |
Iterable<LocalizationsDelegate> |
Flutter 本地化代理 |
NyLocaleHelper
NyLocaleHelper 是一个用于区域操作的静态工具类。它提供了检测当前区域、检查 RTL 支持和创建 Locale 对象的方法。
// Get the current system locale
Locale locale = NyLocaleHelper.getCurrentLocale(context: context);
// Get language and country codes
String langCode = NyLocaleHelper.getLanguageCode(context: context); // 'en'
String? countryCode = NyLocaleHelper.getCountryCode(context: context); // 'US' or null
// Check if current locale matches
bool isEnglish = NyLocaleHelper.matchesLocale(context, 'en');
bool isUsEnglish = NyLocaleHelper.matchesLocale(context, 'en', 'US');
// RTL detection
bool isRtl = NyLocaleHelper.isRtlLanguage('ar'); // true
bool currentIsRtl = NyLocaleHelper.isCurrentLocaleRtl(context: context);
// Get text direction
TextDirection direction = NyLocaleHelper.getTextDirection('ar'); // TextDirection.rtl
TextDirection currentDir = NyLocaleHelper.getCurrentTextDirection(context: context);
// Create a Locale from strings
Locale newLocale = NyLocaleHelper.toLocale('en', 'US');
完整 API 参考
| 方法 | 返回值 | 描述 |
|---|---|---|
getCurrentLocale({context}) |
Locale |
获取当前系统区域设置 |
getLanguageCode({context}) |
String |
获取当前语言代码 |
getCountryCode({context}) |
String? |
获取当前国家代码 |
matchesLocale(context, languageCode, [countryCode]) |
bool |
检查当前区域是否匹配 |
isRtlLanguage(languageCode) |
bool |
检查语言代码是否为 RTL |
isCurrentLocaleRtl({context}) |
bool |
检查当前区域是否为 RTL |
getTextDirection(languageCode) |
TextDirection |
获取语言的 TextDirection |
getCurrentTextDirection({context}) |
TextDirection |
获取当前区域的 TextDirection |
toLocale(languageCode, [countryCode]) |
Locale |
从字符串创建 Locale |
rtlLanguages 常量包含:ar、he、fa、ur、yi、ps、ku、sd、dv。
从控制器更改语言
如果您在页面中使用控制器,可以从 NyController 更改语言:
class SettingsController extends NyController {
void switchToSpanish() {
changeLanguage('es');
}
void switchToEnglishNoRestart() {
changeLanguage('en', restartState: false);
}
}
restartState 参数控制更改语言后是否重启应用。如果您想自己处理 UI 更新,将其设置为 false。