调用Navigator.pop(context)退回上页而非关闭EndDrawer的原因及解决方法
Flutter 侧栏关闭问题解决
根因分析
你在page2外层额外套了一层MaterialApp,相当于在原有路由栈之上新增了一个独立的Navigator实例。直接调用Navigator.pop(context)时,使用的context属于上层页面共享的根Navigator,会直接操作根路由栈退回到page1,不会作用于page2内部的Navigator,自然无法只关闭drawer。
解决方案
方案1:使用Scaffold内置方法关闭drawer(最推荐)
Flutter的ScaffoldState已经提供了专门控制drawer开闭的方法,不需要依赖Navigator的pop操作,完全不会影响路由栈:
- 给page2的Scaffold绑定
GlobalKey<ScaffoldState> - 需要关闭endDrawer时调用
scaffoldKey.currentState?.closeEndDrawer()即可
示例代码:
// Page2内定义Scaffold全局key final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( key: _scaffoldKey, endDrawer: const Drawer(), body: Center( child: ElevatedButton( onPressed: () { // 直接调用scaffold的方法关闭endDrawer _scaffoldKey.currentState?.closeEndDrawer(); }, child: const Text("关闭侧栏"), ), ), ), ); }
方案2:指定使用page2内部MaterialApp的Navigator
如果你一定要用pop方法来关闭drawer,需要拿到page2内部MaterialApp对应的Navigator实例:
- 给page2外层的MaterialApp绑定
GlobalKey<NavigatorState> - 通过该key获取内部Navigator,调用pop
示例代码:
// Page2内定义Navigator的全局key final GlobalKey<NavigatorState> _navKey = GlobalKey<NavigatorState>(); @override Widget build(BuildContext context) { return MaterialApp( key: _navKey, home: Scaffold( endDrawer: const Drawer(), body: Center( child: ElevatedButton( onPressed: () { // 调用内部Navigator的pop方法,仅关闭drawer _navKey.currentState?.pop(); }, child: const Text("关闭侧栏"), ), ), ), ); }
方案3:使用Builder获取内部上下文
如果不想定义全局key,可以在Scaffold内部用Builder包裹操作按钮,拿到的context属于page2内部的路由域,直接调用Navigator.pop(context)就只会作用于内部Navigator,不会退到page1:
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( endDrawer: const Drawer(), body: Center( // 用Builder拿到Scaffold层级的内部context child: Builder( builder: (innerContext) { return ElevatedButton( onPressed: () { Navigator.pop(innerContext); }, child: const Text("关闭侧栏"), ); } ), ), ), ); }
内容的提问来源于stack exchange,提问作者anggadaz
相关产品推荐
相关产品推荐

