跳转至正文

SafeArea 与 MediaQuery

了解如何使用 SafeArea 与 MediaQuery 创建自适应应用。

本页讨论如何以及何时使用 SafeAreaMediaQuery widget。

SafeArea

#

SafeArea

#

在最新设备上运行应用时,UI 部分可能被屏幕挖孔遮挡。可用 SafeArea widget 修复,它会内嵌子 widget 以避免侵入(如刘海与相机挖孔)、操作系统 UI(如 Android 状态栏)或物理屏幕圆角。

若不需要此行为,SafeArea 允许禁用任一侧的内边距。默认四侧均启用。

通常建议将 Scaffold widget 的 body 包在 SafeArea 中作为起点,但不必总放在 Widget 树如此高的位置。

例如,若有意让应用延伸到挖孔下方,可将 SafeArea 移到包裹合适内容的位置,其余部分占满全屏。

使用 SafeArea 可确保应用内容不被物理显示特性或操作系统 UI 裁切,并为日后各种挖孔形状的新设备做好准备。

SafeArea 如何用少量代码做到这些?背后它使用 MediaQuery 对象。

MediaQuery

#

MediaQuery

#

SafeArea 节所述,MediaQuery 是创建自适应应用的强大 widget。有时直接使用 MediaQuery,有时使用背后依赖 MediaQuerySafeArea

MediaQuery 提供大量信息,包括应用当前窗口尺寸。它暴露高对比度、文字缩放等无障碍设置,或用户是否使用 TalkBack、VoiceOver 等无障碍服务。MediaQuery 还包含设备显示特性信息,例如是否有铰链或折叠。

SafeArea 使用 MediaQuery 数据计算子 Widget 的内嵌量,具体使用 MediaQuery 的 padding 属性,即被系统 UI、显示挖孔或状态栏部分遮挡的显示区域量。

那么,为何不直接使用 MediaQuery

答案是 SafeArea 做了一件事,使其比裸用 MediaQueryData 更有利:它修改暴露给 SafeArea 子级的 MediaQuery,使 SafeArea 添加的内边距看似不存在。这意味着可嵌套 SafeArea,仅最外层应用避开挖孔与系统 UI 所需的内边距。

随着应用增长和 widget 移动,多个 SafeArea 时不必担心内边距过多;若直接使用 MediaQueryData.padding 则会有问题。

可以SafeArea 包裹 Scaffold 的 body,但不必 必须 放在 widget 树如此高的位置。SafeArea 只需包裹若被前述硬件特性裁切会导致信息丢失的内容。

例如,若有意让应用延伸到挖孔下,可将 SafeArea 移到包裹合适内容的位置,其余占满全屏。顺带说明,AppBar widget 默认如此,因而可延伸到系统状态栏下方。这也是建议用 SafeArea 包裹 Scaffold body 而非整个 Scaffold 的原因。

SafeArea 以通用方式确保应用内容不被裁切,并为日后各种挖孔形状的新设备做好准备。