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

Flutter中能否在Widget build函数外使用国际化字符串?

Flutter国际化字符串无需局限在build函数内的解决办法

不用必须在build函数里定义国际化字符串,这里有几个实用方案可以让你在build外访问这些字符串:

1. 全局持有AppLocalizations实例

创建一个单例类来保存AppLocalizations实例,在App初始化时完成赋值,之后任何地方都能直接调用:

// 全局单例类
class AppLocalizationsHolder {
  static AppLocalizations? _instance;

  static void setInstance(AppLocalizations instance) {
    _instance = instance;
  }

  static AppLocalizations get instance {
    return _instance!;
  }
}

然后在MaterialApp的builder中完成实例注入:

MaterialApp(
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
  locale: const Locale('zh', 'CN'),
  builder: (context, child) {
    final localizations = AppLocalizations.of(context)!;
    AppLocalizationsHolder.setInstance(localizations);
    return child!;
  },
  home: const HomePage(),
)

之后在任意位置(比如工具类、ViewModel)直接使用:

String settingsText = AppLocalizationsHolder.instance.settings;

2. 借助状态管理工具(以Provider为例)

把AppLocalizations实例注入到状态管理容器中,需要时直接从容器读取:

// 在MaterialApp的builder中注入Provider
MaterialApp(
  // ...其他配置
  builder: (context, child) {
    return Provider.value(
      value: AppLocalizations.of(context)!,
      child: child!,
    );
  },
)

在有context的非build方法中读取:

final localizations = Provider.of<AppLocalizations>(context, listen: false);
String settingsText = localizations.settings;

如果是完全没有context的场景(比如全局工具函数),可以通过Provider的全局容器读取:

// 提前保存全局Provider容器
final container = ProviderContainer();

// 在需要的地方读取
final localizations = container.read<AppLocalizations>();

3. 在StatefulWidget的initState中缓存字符串

如果只是在某个State类的非build方法中需要,可以在initState里缓存字符串(注意要借助postFrameCallback确保context可用):

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  late String _settingsText;

  @override
  void initState() {
    super.initState();
    // 等待Widget渲染完成后获取context
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _settingsText = AppLocalizations.of(context)!.settings;
    });
  }

  // 在非build方法中直接使用缓存的字符串
  void _showSettingsDialog() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(title: Text(_settingsText)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _showSettingsDialog,
      child: const Text('打开设置'),
    );
  }
}

内容的提问来源于stack exchange,提问作者Isaac Cooke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:20:43