最新版Flutter无法添加Drawer 调用Scaffold.of(context)报错context未定义
问题根本原因
你当前代码的问题出在上下文查找的逻辑上:
- 你调用
Scaffold.of(context)时使用的context是HomeScreen组件本身的父级上下文,此时Scaffold还未被挂载到当前上下文对应的组件树中,因此无法找到对应的Scaffold实例 - 新版Flutter对上下文查找的合法性检查更严格,旧版本可能存在的隐式容错逻辑被移除,因此之前能运行的代码现在会抛出错误
可行解决方案
下面提供2种常用的修复方案,任选其一即可:
方案1:使用GlobalKey绑定Scaffold(最稳定,不受上下文层级影响)
修改后的完整代码如下:
class HomeScreen extends StatelessWidget { HomeScreen({Key? key}) : super(key: key); // 定义全局Key绑定Scaffold状态 final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( // 给Scaffold绑定Key key: _scaffoldKey, appBar: buildAppbar(), body: const Body(), drawer: DrawerSlide(), ); } AppBar buildAppbar() { return AppBar( elevation: 3, leading: GestureDetector( child: Padding( padding: const EdgeInsets.all(12.0), child: SvgPicture.asset('assets/icons/menu.svg', width: 10, height: 10, fit: BoxFit.fitWidth,), ), // 通过Key调用Scaffold的打开抽屉方法 onTap: () => _scaffoldKey.currentState?.openDrawer(), ), ); } }
方案2:用Builder包裹leading组件,获取子级上下文
Builder组件会生成子树的上下文,这个上下文可以正确找到父级已经挂载的Scaffold实例:
AppBar buildAppbar() { return AppBar( elevation: 3, // 用Builder包裹leading,获取子级上下文 leading: Builder( builder: (context) { return GestureDetector( child: Padding( padding: const EdgeInsets.all(12.0), child: SvgPicture.asset('assets/icons/menu.svg', width: 10, height: 10, fit: BoxFit.fitWidth,), ), // 此处使用Builder提供的context即可正常查找Scaffold onTap: () => Scaffold.of(context).openDrawer(), ); } ), ); }
注意事项
如果不需要自定义菜单按钮样式,Scaffold默认会在存在drawer属性时自动生成左侧菜单按钮,点击即可打开抽屉,不需要额外手动实现点击逻辑。
内容的提问来源于stack exchange,提问作者Deiakk96
相关产品推荐
相关产品推荐

