Skip to main content

SafeArea 和 MediaQuery

本页面讨论如何以及何时使用SafeAreaMediaQuery小部件。

SafeArea

#

在最新的设备上运行你的应用程序时,你可能会遇到UI的一部分被设备屏幕上的缺口遮挡的情况。你可以使用SafeArea小部件来解决这个问题,它会缩进其子小部件以避免干扰(例如凹口和摄像头缺口),以及操作系统UI(例如Android上的状态栏),或者物理显示器的圆角。

如果你不想要这种行为,SafeArea小部件允许你禁用其任意四边的填充。默认情况下,所有四边都是启用的。

通常建议将Scaffold小部件的主体包装在SafeArea中作为一个良好的开端,但你并不总是需要把它放在Widget树的这么高层级。

例如,如果你故意想让你的应用程序延伸到缺口之下,你可以移动SafeArea来包装任何有意义的内容,并让应用程序的其余部分占据全屏。

使用SafeArea可以确保你的应用程序内容不会被物理显示特性或操作系统UI截断,并使你的应用程序即使在具有不同形状和样式的缺口的新的设备进入市场时也能成功运行。

SafeArea如何在少量代码中做到这么多?在幕后,它使用了MediaQuery对象。

MediaQuery

#

正如SafeArea部分所讨论的,MediaQuery是一个用于创建自适应应用程序的强大小部件。有时你会直接使用MediaQuery,有时你会使用SafeArea,它在幕后使用MediaQuery

MediaQuery提供了大量信息,包括应用程序当前的窗口大小。它公开了辅助功能设置,如高对比度模式和文本缩放,或者用户是否正在使用TalkBack或VoiceOver之类的辅助功能服务。MediaQuery还包含有关设备显示器功能的信息,例如是否有铰链或折叠。

SafeArea使用来自MediaQuery的数据来确定其子Widget需要缩进多少。具体来说,它使用MediaQuery的padding属性,这基本上是显示器中被系统UI、显示器缺口或状态栏部分遮挡的部分。

那么,为什么不直接使用MediaQuery呢?

答案是SafeArea做了一件巧妙的事情,这使得它比直接使用MediaQueryData更有益。具体来说,它修改了暴露给SafeArea子元素的MediaQuery,使其看起来好像添加到SafeArea的填充不存在。这意味着你可以嵌套SafeArea,并且只有最顶层的那个才会应用避免缺口和系统UI所需的填充。

随着你的应用程序的增长和移动小部件,如果你有多个SafeArea,你就不必担心应用了过多的填充,而如果你直接使用MediaQueryData.padding,则会出现问题。

你可以用SafeArea包装Scaffold小部件的主体,但你不必把它放在widget树的这么高层级。SafeArea只需要包装那些如果被前面提到的硬件特性截断会导致信息丢失的内容。

例如,如果你故意想让你的应用程序延伸到缺口之下,你可以移动SafeArea来包装任何有意义的内容,并让应用程序的其余部分占据全屏。需要注意的是,这就是AppBar小部件默认执行的操作,它就是如何在系统状态栏下方显示。这也是建议将Scaffold的主体包装在SafeArea中,而不是包装整个Scaffold本身的原因。

SafeArea以通用的方式确保你的应用程序内容不会被截断,并使你的应用程序即使在具有不同形状和样式的缺口的新的设备进入市场时也能成功运行。