Flutter点击按钮触发‘上下文未包含Navigator’错误的问题排查
这个错误的核心原因是:你调用Navigator.push时使用的context是MyApp2组件的上下文,而MyApp2是MaterialApp的父组件。Navigator是由MaterialApp内部创建并维护的,父组件的上下文无法访问到子组件(MaterialApp)内部的Navigator实例,因此抛出该错误。
以下是两种可行的解决方案:
方案一:将首页内容抽为独立Widget
把原来MaterialApp的home中的Scaffold抽成一个新的StatefulWidget,新Widget的上下文可以正常访问到MaterialApp提供的Navigator。
修改后的main.dart代码:
import "package:flutter/material.dart"; import 'package:try_new/new.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp2()); } class MyApp2 extends StatelessWidget { const MyApp2({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( title: "App", home: HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color.fromARGB(255, 6, 2, 11), body: SingleChildScrollView( child: Column( children: <Widget>[ Padding( padding: const EdgeInsets.only(top: 140.0), child: Container( alignment: Alignment.topCenter, child: Image.asset( "assets/images/two.png", height: 120, width: 100, fit: BoxFit.cover, ))), const SizedBox(height: 10), const Text( "Github", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 48), ), const SizedBox(height: 190), Padding( padding: const EdgeInsets.all(8.0), child: SizedBox( child: Material( color: const Color.fromARGB(255, 16, 16, 16), borderRadius: BorderRadius.circular(6), child: TextFormField( style: const TextStyle(color: Colors.white), decoration: const InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(6))), hintText: "Github username", hintStyle: TextStyle( color: Color.fromARGB(255, 115, 115, 113), fontWeight: FontWeight.w500, fontSize: 22), contentPadding: EdgeInsets.only(top: 15, left: 20, bottom: 15)), ), )), ), const SizedBox( height: 2, ), Padding( padding: const EdgeInsets.all(8.0), child: Material( elevation: 1.0, borderRadius: const BorderRadius.all(Radius.circular(8)), color: const Color.fromARGB(255, 43, 136, 212), child: SizedBox( width: 400, child: Ink( decoration: const BoxDecoration( color: Color.fromARGB(255, 43, 136, 212), borderRadius: BorderRadius.all(Radius.circular(8))), child: TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => const MyApp())); }, child: const Text( "Get Your Following Now", style: TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500, ), )), ), ), ), ) ], ), ), ); } }
方案二:用Builder包裹Scaffold
如果不想抽新Widget,可以用Builder组件包裹Scaffold,Builder会提供一个能访问到MaterialApp内部Navigator的上下文。
修改main.dart中MaterialApp的home部分:
return MaterialApp( title: "App", home: Builder( builder: (context) { return Scaffold( backgroundColor: const Color.fromARGB(255, 6, 2, 11), body: SingleChildScrollView( child: Column( children: <Widget>[ // 其余代码保持原样 Padding( padding: const EdgeInsets.all(8.0), child: Material( elevation: 1.0, borderRadius: const BorderRadius.all(Radius.circular(8)), color: const Color.fromARGB(255, 43, 136, 212), child: SizedBox( width: 400, child: Ink( decoration: const BoxDecoration( color: Color.fromARGB(255, 43, 136, 212), borderRadius: BorderRadius.all(Radius.circular(8))), child: TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => const MyApp())); }, child: const Text( "Get Your Following Now", style: TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500, ), )), ), ), ), ) ], ), ), ); }, ), );
额外注意事项
- 代码中的
@OverRide需改为@override(小写r),这是Dart的标准语法 - State类需要指定泛型,比如
State<MyApp2>、State<MyApp>,避免类型警告
内容的提问来源于stack exchange,提问作者Nishant Sharma
相关产品推荐
相关产品推荐

