实现类似ChatGPT安卓App的全屏背景Flutter侧边抽屉
Flutter实现全屏覆盖状态栏/任务栏的侧边抽屉
核心实现思路
要让侧边抽屉完全覆盖状态栏和底部任务栏,关键在于突破Flutter默认的布局约束,同时同步控制系统UI样式与抽屉背景色一致:
- 取消Drawer默认的边距和阴影,让布局可以延伸到系统UI区域
- 动态同步系统状态栏、导航栏的颜色与抽屉背景色
- 利用
MediaQuery获取系统边距,调整抽屉内容的布局范围
完整代码示例
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), theme: ThemeData(primarySwatch: Colors.blue), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); // 切换系统UI样式,匹配抽屉状态 void _updateSystemUI(bool isDrawerOpen) { SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: isDrawerOpen ? Colors.grey[900] : Theme.of(context).primaryColor, statusBarIconBrightness: isDrawerOpen ? Brightness.light : Brightness.dark, systemNavigationBarColor: isDrawerOpen ? Colors.grey[900] : Colors.white, systemNavigationBarIconBrightness: isDrawerOpen ? Brightness.light : Brightness.dark, )); } @override void initState() { super.initState(); _updateSystemUI(false); } @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar(title: const Text("全屏抽屉示例")), body: const Center(child: Text("主页面内容")), // 自定义Drawer,取消默认约束 drawer: Drawer( elevation: 0, backgroundColor: Colors.transparent, child: AnnotatedRegion<SystemUiOverlayStyle>( // 强制Drawer显示时的系统UI样式 value: SystemUiOverlayStyle( statusBarColor: Colors.grey[900], statusBarIconBrightness: Brightness.light, systemNavigationBarColor: Colors.grey[900], systemNavigationBarIconBrightness: Brightness.light, ), child: Container( color: Colors.grey[900], width: MediaQuery.of(context).size.width * 0.75, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 顶部区域延伸到状态栏 Container( padding: EdgeInsets.only( top: MediaQuery.of(context).padding.top, left: 16, bottom: 16, ), child: const Text( "用户名称", style: TextStyle(color: Colors.white, fontSize: 20), ), ), const Divider(color: Colors.grey[700]), // 菜单列表 ListTile( leading: const Icon(Icons.home, color: Colors.white), title: const Text("首页", style: TextStyle(color: Colors.white)), onTap: () => _scaffoldKey.currentState?.closeDrawer(), ), ListTile( leading: const Icon(Icons.settings, color: Colors.white), title: const Text("设置", style: TextStyle(color: Colors.white)), onTap: () => _scaffoldKey.currentState?.closeDrawer(), ), ], ), ), ), ), // 监听抽屉开关状态,同步更新系统UI onDrawerChanged: (isOpen) => _updateSystemUI(isOpen), ); } }
关键细节说明
- 取消Drawer默认约束:设置
drawer.backgroundColor = Colors.transparent和elevation = 0,消除默认的阴影和内边距,让自定义容器可以完全填充抽屉区域。 - AnnotatedRegion强制系统UI样式:在Drawer内容外层包裹该组件,确保抽屉显示时系统UI立即切换,避免样式延迟。
- 利用MediaQuery适配系统边距:通过
MediaQuery.of(context).padding.top获取状态栏高度,让顶部内容自然延伸到状态栏区域。 - 状态监听同步UI:通过
Scaffold的onDrawerChanged回调,在抽屉开关时动态恢复主页面的系统UI样式。
内容的提问来源于stack exchange,提问作者Talha Iqbal
相关产品推荐
相关产品推荐

