如何修复Dart/Flutter中‘Navigator上下文不包含Navigator’错误
问题原因
你调用Navigator.push时用的是MyApp组件的上下文,而Navigator是由MaterialApp提供的,这个上下文属于MaterialApp的父级,并没有包含Navigator实例,所以触发错误提示。
修复方案
有两种简单的修复方式:
方式一:将首页内容抽为独立组件
把原来home里的Scaffold抽成单独的StatelessWidget,这样新组件的上下文是MaterialApp的子级,能正常访问Navigator。
修改后的完整代码:
import 'package:flutter/material.dart'; import 'german_screen.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Vocabulary', theme: ThemeData(), home: const HomeScreen(), // 替换为新组件 ); } } // 新增的首页组件 class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Center(child: Text('Vocabs')), backgroundColor: Colors.teal, ), body: ListView( children: [ InkWell( onTap: () { print("German clicked!"); Navigator.push( context, MaterialPageRoute( builder: (context) => const Screens(Title: "German"), )); }, child: Container( height: 400, decoration: const BoxDecoration( color: Color(0xFF8D6E63), ), child: Center( child: Image.asset( "lib/assets/images/German.png", width: 250, height: 250, fit: BoxFit.contain, )), ), ), Container( height: 400, decoration: const BoxDecoration( color: Color(0xFF00247D), ), child: Center( child: Image.asset( "lib/assets/images/British.png", width: 250, height: 250, fit: BoxFit.contain, ))), Container( height: 400, decoration: const BoxDecoration( color: Color(0xFFC8102E), ), child: Center( child: Image.asset( "lib/assets/images/Turkish.png", width: 250, height: 250, fit: BoxFit.contain, ))), Container( height: 400, decoration: const BoxDecoration( color: Color(0xFF00471B), ), child: Center( child: Image.asset( "lib/assets/images/Arabic.png", width: 250, height: 250, fit: BoxFit.contain, ))), Container( height: 400, decoration: const BoxDecoration( color: Color(0xFFFCC200), ), child: Center( child: Image.asset( "lib/assets/images/Kurdish.png", width: 250, height: 250, fit: BoxFit.contain, ))), ], ), ); } }
方式二:用Builder包裹Scaffold
如果不想抽组件,可以用Builder组件包裹Scaffold,它会提供一个属于MaterialApp子级的上下文:
@override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Vocabulary', theme: ThemeData(), home: Builder( // 添加Builder builder: (context) { return Scaffold( // 原来的Scaffold内容不变 ); }, ), ); }
原理说明
MaterialApp内部会自动创建Navigator实例,只有它的直接或间接子组件的上下文才能访问到这个实例。原来的MyApp组件的上下文是MaterialApp的父级,所以无法找到Navigator,通过抽组件或用Builder,我们能获取到MaterialApp内部的上下文,就能正常执行页面跳转了。
内容的提问来源于stack exchange,提问作者Kurdish Learner
相关产品推荐
相关产品推荐

