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

Flutter中不传递BuildContext,如何在Getter内实现国际化翻译?

无需BuildContext实现Flutter ViewModel国际化的方案

针对你在ViewModel中无法通过BuildContext获取AppLocalizations的问题,下面是几种可行的实现方案:

方案1:初始化ViewModel时传入AppLocalizations实例

直接在创建ViewModel时,从UI层的上下文获取AppLocalizations实例并传入,让ViewModel持有本地化对象。

ViewModel修改代码:

final Article article;
final AppLocalizations localizations;

ArticleViewModel({required this.article, required this.localizations});

String get name {
  return article.name;
}

String get isGood {
  return article.isGoods ? localizations.goods : localizations.services;
}

UI层创建ViewModel时的代码:

// 在Widget的build方法或initState中获取
final localizations = AppLocalizations.of(context)!;
final viewModel = ArticleViewModel(article: targetArticle, localizations: localizations);

优点:实现简单,无额外依赖;缺点:ViewModel与UI层有轻微耦合,每次创建都需要传入实例。


方案2:通过全局状态管理维护本地化实例

使用状态管理工具(如Provider、GetX)维护全局的AppLocalizations或当前Locale,让ViewModel可以直接获取。

以Provider为例:

1. 创建Locale状态管理类

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

class LocaleManager extends ChangeNotifier {
  AppLocalizations? _localizations;
  Locale? _currentLocale;

  AppLocalizations? get localizations => _localizations;

  // 初始化或更新本地化实例
  void updateLocale(Locale locale, BuildContext context) {
    _currentLocale = locale;
    _localizations = AppLocalizations.of(context);
    notifyListeners();
  }
}

2. 在App根节点注册Provider

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => LocaleManager(),
      child: const MyApp(),
    ),
  );
}

3. 在ViewModel中获取本地化实例

String get isGood {
  final localeManager = Provider.of<LocaleManager>(context, listen: false);
  final localizations = localeManager.localizations!;
  return article.isGoods ? localizations.goods : localizations.services;
}

如果ViewModel不在Widget树中,可以通过全局Provider容器获取,或者使用GetX的全局依赖注入方式(如Get.find<LocaleManager>())。

优点:解耦UI与ViewModel,全局统一管理Locale变化;缺点:需要引入状态管理库,增加少量复杂度。


方案3:直接基于Locale使用Intl包获取翻译

绕过AppLocalizations的上下文依赖,直接使用intl包通过Locale键值对获取翻译,同时维护全局Locale变量。

1. 定义翻译映射与全局Locale

import 'package:flutter/material.dart';

class AppTranslations {
  static final Map<String, Map<String, String>> _translations = {
    'en': {
      'goods': 'Goods',
      'services': 'Services',
    },
    'zh': {
      'goods': '商品',
      'services': '服务',
    },
    // 其他语言...
  };

  static String get(String key, Locale locale) {
    return _translations[locale.languageCode]?[key] ?? key;
  }
}

// 全局维护当前Locale
class GlobalLocale {
  static Locale current = const Locale('en');
}

2. 在ViewModel中使用翻译

String get isGood {
  return article.isGoods
      ? AppTranslations.get('goods', GlobalLocale.current)
      : AppTranslations.get('services', GlobalLocale.current);
}

3. 监听AppLocale变化并更新全局变量

在MaterialApp中配置Locale回调:

MaterialApp(
  locale: GlobalLocale.current,
  localeListResolutionCallback: (locales, supportedLocales) {
    final selectedLocale = locales?.first ?? supportedLocales.first;
    GlobalLocale.current = selectedLocale;
    return selectedLocale;
  },
  // 其他配置...
)

优点:完全脱离BuildContext依赖,灵活性高;缺点:需要手动维护翻译映射和Locale更新,适合小型项目或自定义需求场景。

内容的提问来源于stack exchange,提问作者Xavier Soh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:10:59