Flutter:如何从其他Widget中调用openDrawer方法?
解决Header中调用打开EndDrawer的问题
你之前用Scaffold.of(context)无效,是因为Header的上下文(context)不在Scaffold的上下文范围内——AppBar作为Scaffold的参数,它的context无法获取到外层Scaffold的State。下面提供两种可行的解决方案:
方案一:使用GlobalKey
通过GlobalKey直接获取Scaffold的State,从而调用打开抽屉的方法:
- 在Home的State中定义GlobalKey,并绑定到Scaffold上
- 将这个Key传递给Header组件
- 在Header的onPressed中调用Key对应的方法打开EndDrawer
修改后的代码:
Home.dart
class _HomeState extends State<Home> { // 定义Scaffold的GlobalKey final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, // 绑定到Scaffold appBar: Header('App', scaffoldKey: _scaffoldKey), // 传递给Header endDrawer: const Menu(), ); } }
Header.dart
class Header extends StatefulWidget implements PreferredSizeWidget { // 添加scaffoldKey参数 const Header(this.heading, {required this.scaffoldKey, Key? key}) : super(key: key); final String heading; final GlobalKey<ScaffoldState> scaffoldKey; @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); @override State<Header> createState() => _HeaderState(heading); } class _HeaderState extends State<Header> { _HeaderState(this.heading); final String heading; @override Widget build(BuildContext context) { return AppBar( centerTitle: false, actions: <Widget>[ IconButton( icon: const Icon(Icons.menu, size: 30.0), tooltip: '', onPressed: () { // 调用打开EndDrawer的方法 widget.scaffoldKey.currentState?.openEndDrawer(); }, ), ], ); } }
方案二:使用回调函数
通过给Header传递一个回调函数,把打开抽屉的逻辑交给Home组件处理,更符合组件解耦的设计:
- 在Header中定义一个回调参数
- 在Home中实现打开抽屉的逻辑,并传递给Header
- Header的onPressed直接调用这个回调
修改后的代码:
Home.dart
class _HomeState extends State<Home> { @override Widget build(BuildContext context) { return Scaffold( appBar: Header('App', onMenuPressed: () { // 在Home中调用打开EndDrawer的方法 Scaffold.of(context).openEndDrawer(); }), endDrawer: const Menu(), ); } }
Header.dart
class Header extends StatefulWidget implements PreferredSizeWidget { // 添加回调参数 const Header(this.heading, {required this.onMenuPressed, Key? key}) : super(key: key); final String heading; final VoidCallback onMenuPressed; @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); @override State<Header> createState() => _HeaderState(heading); } class _HeaderState extends State<Header> { _HeaderState(this.heading); final String heading; @override Widget build(BuildContext context) { return AppBar( centerTitle: false, actions: <Widget>[ IconButton( icon: const Icon(Icons.menu, size: 30.0), tooltip: '', onPressed: widget.onMenuPressed, // 直接调用回调 ), ], ); } }
注意:因为你使用的是endDrawer,所以要调用openEndDrawer()而不是openDrawer()——后者是针对左侧默认抽屉的。
内容的提问来源于stack exchange,提问作者django
相关产品推荐
相关产品推荐

