如何在StatefulShellRoute.indexedStack底部导航栏使用本地化字符串并解决空值问题
解决方案
1. 先确保MaterialApp.router的本地化配置完整
这是获取AppLocalizations的基础,必须在MaterialApp.router中配置好本地化代理和支持的语言:
MaterialApp.router( // 其他原有配置 localizationsDelegates: const [ AppLocalizations.delegate, // 你的自定义本地化代理 GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en'), // 按需添加你支持的语言 Locale('zh'), ], routerConfig: goRouter, )
2. 替换空断言为安全获取方式
直接用!强制解包是空指针错误的根源,改用以下两种安全方式:
方式一:空合并运算符兜底默认值
NavigationDestination( label: AppLocalizations.of(context)?.app_name ?? '首页', icon: const Icon(Icons.local_drink), ),
方式二:先判断再渲染,避免空值
在AppFrameWithNavBar的build方法中先检查本地化实例是否存在,不存在时返回临时加载组件:
@override Widget build(BuildContext context, WidgetRef ref) { _listenForConnectivityChanges(ref, context); final localizations = AppLocalizations.of(context); // 本地化未加载完成时,显示加载占位 if (localizations == null) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } return Scaffold( body: navigationShell, bottomNavigationBar: NavigationBar( selectedIndex: navigationShell.currentIndex, destinations: [ NavigationDestination( label: localizations.app_name, icon: const Icon(Icons.local_drink), ), NavigationDestination( label: localizations.parties, icon: const Icon(Icons.meeting_room), ), NavigationDestination( label: localizations.user, icon: const Icon(Icons.manage_accounts), ), ], onDestinationSelected: _goBranch, ), ); }
3. 确保上下文能访问到Localizations
如果上述方法仍无效,可能是StatefulShellRoute的builder上下文未包含Localizations作用域,用Builder组件包裹AppFrameWithNavBar即可解决:
final goRouter = GoRouter( // 其他原有配置 routes: [ StatefulShellRoute.indexedStack( builder: (context, state, navigationShell) { // 用Builder包裹,获取MaterialApp内部的上下文 return Builder( builder: (context) => AppFrameWithNavBar(navigationShell: navigationShell), ); }, // 其他路由配置 ), ], );
可选:用扩展方法简化调用
给BuildContext加个扩展,让本地化调用更简洁,同时通过断言避免遗漏配置:
extension LocalizationsExtension on BuildContext { AppLocalizations get l10n { final localizations = AppLocalizations.of(this); assert(localizations != null, '请检查MaterialApp的本地化配置是否完整'); return localizations!; } }
之后在组件里可以直接这样用:
label: context.l10n.app_name,
内容的提问来源于stack exchange,提问作者Belz123PL
相关产品推荐
相关产品推荐

