如何在无Flutter依赖的纯Dart包中使用Intl实现本地化?
在纯Dart包中使用Intl实现本地化
1. 添加依赖
在包的pubspec.yaml中添加以下依赖:
dependencies: intl: ^0.18.1 # 替换为最新版本 dev_dependencies: intl_translation: ^0.17.16 build_runner: ^2.4.6
执行dart pub get完成依赖安装。
2. 创建ARB本地化资源文件
在包的lib目录下新建l10n文件夹,用于存放多语言资源:
- 创建
intl_en.arb(英文资源):{ "requireLogin": "Please log in first", "@requireLogin": { "description": "提示用户需要登录" }, "networkError": "Network connection failed", "@networkError": { "description": "网络异常提示" } } - 创建
intl_zh.arb(中文资源):{ "requireLogin": "请先登录", "@requireLogin": { "description": "提示用户需要登录" }, "networkError": "网络连接失败", "@networkError": { "description": "网络异常提示" } }
注意:所有语言文件的键名必须完全一致,
@键名用于添加描述,帮助翻译人员理解上下文。
3. 生成本地化Dart代码
3.1 创建本地化引导文件
在lib目录下新建app_localizations.dart,内容如下:
import 'package:intl/intl.dart'; import 'package:intl/message_lookup_by_library.dart'; import 'package:intl/src/intl_helpers.dart'; import 'l10n/messages_all.dart'; class AppLocalizations { // 加载指定语言的本地化资源 static Future<AppLocalizations> load(Locale locale) { final localeName = Intl.canonicalizedLocale(locale.languageCode); return initializeMessages(localeName).then((_) { Intl.defaultLocale = localeName; return AppLocalizations(); }); } // 获取实例 static AppLocalizations of() => AppLocalizations(); // 本地化字符串 getter,对应ARB文件中的键 String get requireLogin => Intl.message( 'Please log in first', // 默认英文(与intl_en.arb一致) name: 'requireLogin', desc: '提示用户需要登录', // 与ARB中的@requireLogin.description一致 ); String get networkError => Intl.message( 'Network connection failed', name: 'networkError', desc: '网络异常提示', ); }
3.2 生成自动代码
在终端执行以下命令,生成l10n目录下的自动代码文件:
dart run build_runner build
执行完成后,lib/l10n会生成messages_all.dart、messages_en.dart等文件,这些文件无需手动修改。
4. 集成到现有业务类
4.1 结合CurrentLocal切换语言
修改CurrentLocal单例,在语言切换时触发本地化资源加载:
import 'package:intl/intl.dart'; import 'app_localizations.dart'; class CurrentLocal { static final CurrentLocal instance = CurrentLocal._(); CurrentLocal._(); Locale? _uiLocal; Locale? get uiLocal => _uiLocal; // 监听语言变化的Stream(假设你已有类似机制) final _localeStreamController = StreamController<Locale?>.broadcast(); Stream<Locale?> get localeStream => _localeStreamController.stream; void setUiLocal(Locale locale) { _uiLocal = locale; // 加载对应语言的本地化资源 AppLocalizations.load(locale); // 通知监听者语言已切换 _localeStreamController.add(locale); } // 记得在合适的地方关闭StreamController,避免内存泄漏 void dispose() => _localeStreamController.close(); }
4.2 替换DataResponse的硬编码字符串
将DataResponse的静态实例改为动态获取本地化字符串:
import 'app_localizations.dart'; class DataResponse<T> { final String message; final T? data; final bool success; const DataResponse._({ required this.message, this.data, required this.success, }); // 需要登录的响应 static DataResponse<T> requireLogin<T>() => DataResponse._( message: AppLocalizations.of().requireLogin, success: false, ); // 网络错误的响应 static DataResponse<T> networkError<T>() => DataResponse._( message: AppLocalizations.of().networkError, success: false, ); // 其他业务响应同理 }
5. 注意事项
- 每次新增或修改ARB文件后,都需要重新执行
dart run build_runner build更新自动生成的代码。 - 如果你的
CurrentLocal使用自定义语言标识(如字符串'zh-CN'),需转换为Intl的Locale对象:Locale('zh', 'CN')。 - 纯Dart包无需依赖Flutter,所有本地化逻辑仅依赖
intl包自身API。
内容的提问来源于stack exchange,提问作者coolboy
相关产品推荐
相关产品推荐

