Flutter导航异常:调用Navigator.pushNamed报无Navigator上下文错误
我在Flutter中实现带持久化组件的导航功能,调用Navigator.of(context).pushNamed('/route')时触发「Navigator operation requested with a context that does not include a Navigator」错误。尝试改用home属性替代initialRoute,问题仍未解决。
相关代码
main.dart
@override Widget build(BuildContext context) { return MaterialApp( title: 'Benchside', theme: ThemeData( fontFamily: 'GemunuLibre', ), builder: (context, child) => BaseWidget(content: child!), initialRoute: '/', routes: { '/': (context) => const HomePage(), '/profile': (context) => const ProfilePage(), }, onGenerateRoute: (settings) { if (settings.name == '/') { return MaterialPageRoute(builder: (context) => const HomePage()); } else if (settings.name == '/profile') { return MaterialPageRoute(builder: (context) => const ProfilePage()); } }, ); }
BaseWidget.dart
@override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color.fromARGB(0xFF, 0xFA, 0xFA, 0xFA), body: SafeArea( minimum: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), child: CColumn(children: [ //HEADER AppBar( title: const Text( 'BENCHSIDE', style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), ), centerTitle: true, backgroundColor: const Color.fromARGB(0xFF, 0xFA, 0xFA, 0xFA), scrolledUnderElevation: 0.0, leading: IconButton( onPressed: () { }, icon: const Image( image: AssetImage('assets/images/setting.png'), width: 30.0, height: 30.0, color: Color.fromARGB(0xFF, 0xA4, 0xA4, 0xA4), ), ), actions: [ IconButton( onPressed: () {}, icon: const Image( image: AssetImage('assets/images/announcements.png'), width: 30.0, height: 30.0, color: Color.fromARGB(0xFF, 0xA4, 0xA4, 0xA4), ) ) ], ), // PAGE VIEWER Expanded(child: content,), // NAVIGATION BAR Container( decoration: const BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ GestureDetector( onTap: () => {Navigator.pushNamed(context, '/')}, child: const Image(image: AssetImage('assets/images/home.png'), width: 30.0, height: 30.0, ),), Image(image: AssetImage('assets/images/ranking.png'), width: 30.0, height: 30.0, color: Color.fromARGB(0xFF, 0xA4, 0xA4, 0xA4),), Image(image: AssetImage('assets/images/community.png'), width: 30.0, height: 30.0, color: Color.fromARGB(0xFF, 0xA4, 0xA4, 0xA4),), GestureDetector( onTap: () => {Navigator.of(context).pushNamed('/profile')}, child: const CircleAvatar() ), ],), )], ),), ); }
问题原因
BaseWidget中使用的context属于MaterialApp层级,无法访问MaterialApp内部创建的Navigator实例——Navigator是MaterialApp的子组件,当前上下文的层级高于Navigator,自然找不到它。
解决方案
方案一:使用GlobalKey获取NavigatorState
在main.dart顶层定义全局Key:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
在MaterialApp中配置该Key:
return MaterialApp( navigatorKey: navigatorKey, // 其他属性保持不变 );
修改BaseWidget中的导航逻辑:
// 首页跳转 GestureDetector( onTap: () => navigatorKey.currentState?.pushNamed('/'), child: const Image(/* ... */), ), // 个人页跳转 GestureDetector( onTap: () => navigatorKey.currentState?.pushNamed('/profile'), child: const CircleAvatar(), ),
方案二:用Builder包裹导航栏获取子级上下文
在BaseWidget的导航栏部分,用Builder包裹Row,通过Builder提供的上下文访问Navigator:
Container( decoration: const BoxDecoration(/* ... */), child: Builder( builder: (navContext) { return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ GestureDetector( onTap: () => Navigator.pushNamed(navContext, '/'), child: const Image(/* ... */), ), // 其他图标组件... GestureDetector( onTap: () => Navigator.of(navContext).pushNamed('/profile'), child: const CircleAvatar(), ), ], ); }, ), )
额外优化
你的main.dart中同时定义了routes和onGenerateRoute,这会导致routes被忽略,建议删除onGenerateRoute,仅保留routes配置即可满足现有路由需求。
内容的提问来源于stack exchange,提问作者AR0106
相关产品推荐
相关产品推荐

