Flutter中如何实现位于AppBar下方的Navigation Drawer导航抽屉
实现方案
默认Flutter的Scaffold组件提供的drawer属性默认会覆盖整个页面高度(包含AppBar区域),要实现抽屉在AppBar下方展示,用嵌套Scaffold的方案即可:
- 外层
Scaffold配置你的AppBar,作为页面全局顶部导航 - 内层
Scaffold放在外层Scaffold的body属性中,内层Scaffold配置drawer属性,此时内层的抽屉就只会在内层Scaffold的区域(也就是AppBar下方)展开
完整可运行示例代码
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '抽屉效果示例', theme: ThemeData(primarySwatch: Colors.blue), home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { // 定义全局Key用来控制内层Scaffold的抽屉 final GlobalKey<ScaffoldState> _innerScaffoldKey = GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { // 外层Scaffold:配置全局AppBar return Scaffold( appBar: AppBar( title: const Text('导航页'), // 手动配置菜单按钮,点击触发内层抽屉展开 leading: IconButton( icon: const Icon(Icons.menu), onPressed: () => _innerScaffoldKey.currentState?.openDrawer(), ), ), // 外层body放内层Scaffold,抽屉配置在内层 body: Scaffold( key: _innerScaffoldKey, drawer: Drawer( child: ListView( padding: EdgeInsets.zero, children: const [ DrawerHeader( decoration: BoxDecoration(color: Colors.blue), child: Text('侧边栏头部', style: TextStyle(color: Colors.white, fontSize: 24)), ), ListTile(leading: Icon(Icons.home), title: Text('首页')), ListTile(leading: Icon(Icons.notifications), title: Text('消息通知')), ListTile(leading: Icon(Icons.settings), title: Text('系统设置')), ListTile(leading: Icon(Icons.person), title: Text('个人中心')), ], ), ), // 内层Scaffold的body为你的页面主体内容 body: const Center(child: Text('页面主体内容区域')), ), ); } }
补充说明
- 如果需要从右侧滑出抽屉,把内层Scaffold的
drawer换成endDrawer即可,同时把AppBar的菜单按钮放到actions列表中,调用openEndDrawer()方法触发即可。 - 抽屉的宽度、动画效果、子项布局都可以通过Drawer组件的原生属性自定义,和默认Drawer的用法完全一致,没有额外适配成本。
内容的提问来源于stack exchange,提问作者garawaa garawaa
相关产品推荐
相关产品推荐

