Drawer如何使用
是什么
Drawer 是一个从屏幕边缘滑出的侧边导航面板,常用于在应用中提供导航菜单、设置选项、用户资料等内容。
它通常和 Scaffold 搭配使用:
- 放在
Scaffold.drawer(左侧抽屉) - 或
Scaffold.endDrawer(右侧抽屉)
打开关闭方式
打开和关闭 Drawer 的方式
除了点击 AppBar 自动弹出外,也可以手动控制 Drawer 的打开关闭:
Scaffold.of(context).openDrawer(); // 打开左侧
Scaffold.of(context).openEndDrawer(); // 打开右侧
Navigator.pop(context); // 关闭抽屉
Get.back(); // 关闭抽屉
注意:要在
Builder或context在Scaffold内部时才能调用Scaffold.of(context)
Scaffold.drawer的默认行为
当你在 Scaffold 中提供了 drawer 时:
AppBar会自动在左上角显示一个“汉堡菜单图标”(三条杠),叫做DrawerButton- 点击它会自动调用
Scaffold.of(context).openDrawer()打开左侧抽屉
这个图标只会出现在
drawer有值而且AppBar没有自己指定leading时
常用属性
Drawer 本身的属性不多,主要用的是它的 child(通常是 ListView) 里放什么内容。
| 属性 | 类型 | 作用 |
|---|---|---|
child |
Widget | Drawer 的内容主体 |
elevation |
double | 阴影高度 |
backgroundColor |
Color | 背景颜色 |
width |
double | Drawer 的宽度 |
shape |
ShapeBorder | Drawer 的外形边框(比如圆角) |
常用的相关组件
| 组件 | 用途 |
|---|---|
Drawer |
抽屉整体容器 |
DrawerHeader |
抽屉顶部的标题区域(可放用户信息、头像) |
ListView |
容纳菜单项,支持滚动 |
ListTile |
单个菜单项 |
UserAccountsDrawerHeader |
一个带头像、用户名、邮箱等信息的专用头部 |
案例
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MyDrawerDemo()));
}
class MyDrawerDemo extends StatelessWidget {
const MyDrawerDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Drawer & EndDrawer 示例'),
actions: [
// AppBar 右上角按钮,用于打开右侧抽屉
Builder(
builder: (context) {
return IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
// 打开右侧抽屉
Scaffold.of(context).openEndDrawer();
},
);
},
),
],
),
// 左侧抽屉
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
// UserAccountsDrawerHeader 显示用户信息
const UserAccountsDrawerHeader(
// 账户名称
accountName: Text('张三'),
// 账户邮箱
accountEmail: Text('zhangsan@example.com'),
// 头像
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage('assets/avatar.png'),
),
// 头部背景
decoration: BoxDecoration(color: Colors.blue),
),
// 主页
ListTile(
leading: const Icon(Icons.home),
title: const Text('主页'),
onTap: () {
Navigator.pop(context); // 关闭抽屉
},
),
ListTile(
leading: const Icon(Icons.person),
title: const Text('个人资料'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
// 右侧抽屉
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
// DrawerHeader 显示标题
const DrawerHeader(
decoration: BoxDecoration(color: Colors.green),
child: Text('设置菜单', style: TextStyle(color: Colors.white)),
),
// 深色模式开关
SwitchListTile(
value: true,
onChanged: (v) {},
title: const Text('深色模式'),
),
// 退出登录
ListTile(
leading: const Icon(Icons.logout),
title: const Text('退出登录'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: Center(
child: Builder(
builder: (context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 手动打开左侧抽屉
Scaffold.of(context).openDrawer();
},
child: const Text('打开左侧抽屉'),
),
ElevatedButton(
onPressed: () {
// 手动打开右侧抽屉
Scaffold.of(context).openEndDrawer();
},
child: const Text('打开右侧抽屉'),
),
],
);
},
),
),
);
}
}
AppBar的默认情况
automaticallyImplyLeading
在AppBar中有一个配置:
AppBar(
automaticallyImplyLeading: true, // 默认就是 true
)
当 automaticallyImplyLeading: true 时,AppBar 会自动决定是否在左上角显示一个「leading」图标(通常是返回箭头或 Drawer 菜单图标)。
它会按以下优先级判断:
| 场景 | 默认显示的图标 |
|---|---|
有 drawer 且 leading 为空 |
显示「三条杠」菜单图标 (DrawerButton) |
有可返回的上一级路由 (Navigator.canPop) 且 leading 为空 |
显示返回箭头 (BackButton) |
| 都没有 | 不显示任何图标 |
当automaticallyImplyLeading: false时,就表示不要自动生成任何图标,哪怕当前页面可以返回、或有 drawer,也都不显示。
修改 drawer的默认图标
只要自己设置 AppBar.leading 属性,覆盖掉默认的 DrawerButton:
AppBar会自动在左上角显示一个“汉堡菜单图标”(三条杠),叫做DrawerButton点击它会自动调用
Scaffold.of(context).openDrawer()打开左侧抽屉
appBar: AppBar(
title: const Text('自定义 Drawer 图标'),
leading: Builder(
builder: (context) {
return IconButton(
icon: const Icon(Icons.menu_open), // ← 自定义图标
onPressed: () {
Scaffold.of(context).openDrawer(); // 手动打开 Drawer
},
);
},
),
),
如果想完全隐藏左上角图标
appBar: AppBar(
automaticallyImplyLeading: false,
)