You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:42:43