在 Flutter 中,SafeArea 是一个用于确保 UI 内容不被设备屏幕的系统元素(如状态栏、导航栏、刘海屏、底部 Home Indicator 等)遮挡的重要布局组件。
作用
- 自动为子组件添加内边距(padding),避开系统 UI 遮挡区域。
- 适配各种异形屏(如 iPhone 刘海屏、Android 挖孔屏、折叠屏等)。
- 默认情况下,会处理 顶部、底部、左侧、右侧 四个方向的安全区域。
用法
Scaffold(
body: SafeArea(
child: Column(
children: [
Text("顶部内容"),
Text("底部内容"),
],
),
),
)
备注: 将 SafeArea 包裹在 Scaffold.body 中是推荐做法,可避免内容被状态栏或底部导航栏遮挡 。
常用的属性
| 属性 | 说明 | 默认值 |
|---|---|---|
top |
是否启用顶部安全区域 | true |
bottom |
是否启用底部安全区域 | true |
left |
是否启用左侧安全区域 | true |
right |
是否启用右侧安全区域 | true |
minimum |
额外最小内边距(如 EdgeInsets.only(bottom: 20)) |
EdgeInsets.zero |
maintainBottomViewPadding |
是否保留底部视图填充(用于沉浸式场景) | false |
示例:仅避开顶部和底部
SafeArea(
top: true,
bottom: true,
left: false,
right: false,
child: YourWidget(),
)
推荐使用场景:
- 页面没有使用
AppBar(因为AppBar已自动处理顶部安全区)。 - 内容位于页面底部,需避开 Android 导航栏或 iOS Home Indicator。
- 开发全屏应用(如游戏、视频播放器)但希望关键控件不被遮挡。
- 适配折叠屏、平板横屏等非标准设备 。
无需使用场景:
- 页面已包含
AppBar或BottomNavigationBar(它们自带安全区适配)。 - 设计要求内容覆盖全屏(如背景图、沉浸式体验)。
原理
SafeArea 内部通过 MediaQuery.of(context).padding 获取系统 UI 占用的空间,并返回一个带相应内边距的 Padding 小部件。同时,它会用 MediaQuery.removePadding 防止子组件重复获取 padding,避免布局错乱 。
建议
- **默认包裹
Scaffold.body**,除非有特殊需求 。 - 不要包裹整个
Scaffold,否则会影响AppBar的正常显示 。 - 可结合
minimum属性为老设备提供默认安全距离 。