Flutter如何通过Drawer菜单项切换Scaffold的body展示内容
解决方案
该需求完全可以实现,核心是通过父组件状态管理+子组件回调的方式,让Home组件感知抽屉的点击动作,触发自身状态更新替换Scaffold的body内容,修改步骤如下:
- 第一步:修改
main.dart,将无状态的Home组件改为有状态组件,新增状态变量存储当前展示的body组件,接收抽屉点击的回调更新状态
import 'package:flutter/material.dart'; import 'Navbars/navbar.dart'; import 'Pages/settings.dart'; import 'Pages/stage.dart'; // 新增导入stage页面 void main() => runApp(MaterialApp(home: Home())); // 改为有状态组件 class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { // 存储当前展示的body组件,默认显示设置页 Widget _currentBody = const settingsPage(); // 切换body的方法 void _updateBody(Widget newBody) { setState(() { _currentBody = newBody; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("MyApp"), centerTitle: true, backgroundColor: Colors.redAccent, ), body: _currentBody, floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ FloatingActionButton( onPressed: () {}, child: const Text("Stage"), backgroundColor: Colors.green, ), FloatingActionButton( onPressed: () {}, child: const Text("Dev"), backgroundColor: Colors.green, ), ], ), // 给NavBar传回调方法 drawer: NavBar(onMenuTap: _updateBody), ); } }
- 第二步:修改
navbar.dart,新增回调参数,点击菜单项时触发回调通知父组件切换页面
import 'package:flutter/material.dart'; import '../Pages/stage.dart'; // 导入stage页面 class NavBar extends StatelessWidget { // 新增回调参数,点击菜单项时触发 final Function(Widget) onMenuTap; const NavBar({Key? key, required this.onMenuTap}) : super(key: key); @override Widget build(BuildContext context) { return Drawer( child: ListView( padding: EdgeInsets.zero, children: [ UserAccountsDrawerHeader( accountName: const Text("User"), accountEmail: const Text("User Test"), currentAccountPicture: CircleAvatar( child: ClipOval( child: Image.network( 'https://oflutter.com/wp-content/uploads/2021/02/girl-profile.png', fit: BoxFit.cover, width: 90, height: 90, ), ), ), decoration: BoxDecoration( color: Colors.blue, image: DecorationImage( fit: BoxFit.fill, image: NetworkImage( 'https://oflutter.com/wp-content/uploads/2021/02/profile-bg3.jpg')), ), ), ListTile( leading: const Icon(Icons.notifications), title: const Text('Alerts'), onTap: () => {}, trailing: ClipOval( child: Container( color: Colors.red, width: 40, height: 40, child: const Center( child: Text( 'Soon', style: TextStyle( color: Colors.white, fontSize: 12, ), ), ), ), ), ), ListTile( leading: const Icon(Icons.settings), title: const Text('Settings'), onTap: () { Navigator.of(context).pop(); // 触发回调,传入要切换的stagePage onMenuTap(const stagePage()); }, ), const Divider(), ListTile( title: const Text('Exit'), leading: const Icon(Icons.exit_to_app), onTap: () => null, ), ], ), ); } }
- 第三步:确认文件导入路径和你本地项目结构匹配即可,后续需要新增更多抽屉切换的页面,只需要在点击事件的回调里传入对应的页面组件即可。
内容的提问来源于stack exchange,提问作者DevFromI
相关产品推荐
相关产品推荐

