Flutter侧边菜单跳转页面触发Navigator上下文错误的求助
问题根源排查
两个明显的结构错误共同导致了当前跳转失败、报错的问题:
- Navigator上下文匹配错误:你当前用在
Navigator.push里的context,是Mains类里构建MaterialApp时的上下文。而Navigator是MaterialApp内部才会创建的组件,这个外部上下文根本不在Navigator的组件子树里,自然找不到可用的Navigator实例,才会抛出“上下文不包含Navigator”的报错。 - 页面层级冗余错误:你给
Seals、Object两个跳转目标页面各自单独套了一层MaterialApp。正常来说整个应用只需要在最顶层放一个MaterialApp当根组件就够了,每多包一层MaterialApp就会创建一套独立的Navigator栈,会导致跳转后的页面自带独立AppBar、没法正常回退,侧边菜单的跳转逻辑也会被割裂。
具体修复步骤
- 把原来直接写在
Mains类里的主页Scaffold(包含顶部AppBar、侧边抽屉菜单)抽成独立的页面组件。这样抽屉菜单的点击回调里拿到的上下文,就处于MaterialApp内部、属于Navigator的子组件树,能正常找到Navigator执行跳转。 - 删掉
Seals、Object类里多余的MaterialApp包裹,直接把两个API加载页面(JsonParseSeals、JsonParseObject)放到新页面的Scaffold组件里即可。 - 点击侧边菜单项跳转前,先把弹出的侧边抽屉菜单关掉,避免跳转后菜单还留在屏幕上。
修正后的核心参考代码
import 'package:flutter/material.dart'; import 'package:flutter_app_seals/model/object_list/JsonObject.dart'; import 'package:flutter_app_seals/model/seals_list/JsonSeals.dart'; void main() { runApp(Mains()); } // 顶层应用根组件,只保留一个MaterialApp class Mains extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } // 抽离的主页,包含侧边菜单 class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Text('Seals Log'), ), drawer: Drawer( child: ListView( children: <Widget>[ ListTile( title: Text("Seals List"), trailing: Icon(Icons.arrow_back), onTap:() { // 先关闭侧边菜单,再执行跳转 Navigator.pop(context); Navigator.push( context, MaterialPageRoute(builder: (context) => SealsPage()), ); } ), ListTile( title: Text("Object List"), trailing: Icon(Icons.arrow_downward), onTap:() { // 先关闭侧边菜单,再执行跳转 Navigator.pop(context); Navigator.push( context, MaterialPageRoute(builder: (context) => ObjectPage()), ); } ) ], ), ), ); } } // 封印列表页,移除多余的MaterialApp包裹 class SealsPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Seals List")), body: JsonParseSeals(), ); } } // 对象列表页,移除多余的MaterialApp包裹 class ObjectPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Object List")), body: JsonParseObject(), ); } }
补充提示:跳转的目标页面自带的AppBar会自动生成返回箭头,不需要额外写返回逻辑,点击就能回到带侧边菜单的主页。
内容的提问来源于stack exchange,提问作者MaksIngenr
相关产品推荐
相关产品推荐

