Flutter如何在initState中获取MaterialApp的context解决弹窗报错
Flutter easy_localization下initState弹Dialog报No MaterialLocalizations错误解决方案
报错的核心原因是你调用
showDialog时使用的context未包含MaterialApp注入的MaterialLocalizations配置,搭配easy_localization做非默认语言启动时,旧上下文未同步加载到目标语言的本地化资源,就会触发该异常。
下面是三种可行解决方案:
方案1:全局NavigatorKey获取MaterialApp上下文(最推荐)
该方案完全规避了当前页面上下文的依赖问题,是全局调用弹窗/路由的通用解决方案:
- 在全局位置定义导航键:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
- 将该key绑定到你的
MaterialApp配置中(如果是EasyLocalization嵌套的MaterialApp,直接绑在MaterialApp的属性上即可):
MaterialApp( navigatorKey: navigatorKey, // 其余配置保持不变,包括easy_localization的localizationsDelegates、supportedLocales等 )
- 修改你的initState弹窗逻辑,使用全局key的上下文:
@override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) async { await showDialog<String>( barrierDismissible: false, // 替换为全局导航键的上下文即可 context: navigatorKey.currentContext!, builder: (BuildContext context) => ApproveDialogue( child: ChooseLanguageDialogue(), )); }); }
方案2:用Builder包裹当前页面获取子上下文
如果不想用全局key,可以在当前页面的build方法中用Builder包裹内容,拿到MaterialApp下层的上下文:
@override Widget build(BuildContext context) { return Scaffold( // 用Builder包裹body,拿到的context已经包含MaterialApp的配置 body: Builder( builder: (BuildContext innerContext) { // 后续如果用innerContext弹dialog就不会报错 return 你的页面内容组件; }, ), ); }
注意该方案需要你把弹窗逻辑的上下文替换为Builder返回的innerContext,适配成本比方案1高。
方案3:校验easy_localization配置
确认你的MaterialApp已正确配置easy_localization的相关参数,避免是配置错误导致的本地化资源加载失败:
MaterialApp( localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, // 其余配置 )
内容的提问来源于stack exchange,提问作者bihire boris
相关产品推荐
相关产品推荐

