使用MaterialPageRoute跳转新Dart页面报Navigator上下文异常,求排查
你遇到的Navigator operation requested with a context that does not include a Navigator错误,核心原因是你用来触发跳转的context没有关联到MaterialApp内部的Navigator实例。
问题根源
你的Belajar widget直接返回了MaterialApp,而Belajar的context是MaterialApp的父级上下文——Flutter的context是沿着widget树向上查找依赖的,这个父级context根本找不到MaterialApp提供的Navigator服务,所以调用Navigator.push时就会报错。
两种修复方法
方法1:将首页内容抽成独立的子Widget
把原来的Scaffold部分拆成一个单独的HomePage widget,这样HomePage的context就属于MaterialApp的子级,能正常访问Navigator:
import 'package:flutter/material.dart'; import 'package:hello_world/settings_page.dart'; void main() => runApp(Belajar()); class Belajar extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), // 使用独立的首页Widget ); } } // 独立的首页Widget,context属于MaterialApp内部 class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: Icon(Icons.android), title: Text('Hello World'), actions: [ IconButton( icon: Icon(Icons.settings), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SettingsPage(), ), ); }, ) ], ), ); } }
方法2:使用Builder Widget包裹Scaffold
Builder会提供一个属于当前widget子树的context,把它套在Scaffold外面,就能拿到MaterialApp内部的context:
import 'package:flutter/material.dart'; import 'package:hello_world/settings_page.dart'; void main() => runApp(Belajar()); class Belajar extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Builder( builder: (innerContext) { // 这个context属于MaterialApp内部 return Scaffold( appBar: AppBar( leading: Icon(Icons.android), title: Text('Hello World'), actions: [ IconButton( icon: Icon(Icons.settings), onPressed: () { Navigator.push( innerContext, MaterialPageRoute( builder: (context) => SettingsPage(), ), ); }, ) ], ), ); }, ), ); } }
补充说明
你的settings_page.dart代码是没问题的——SettingsPage作为MaterialApp的子页面,它的context能正常访问Navigator,所以Navigator.pop(context)可以正确返回上一页。
内容的提问来源于stack exchange,提问作者caeruleum
相关产品推荐
相关产品推荐

