SafeArea 與 MediaQuery
瞭解如何使用 SafeArea 和 MediaQuery 來建立自適應應用。
本頁討論如何以及何時使用 SafeArea 和 MediaQuery 元件。
SafeArea
#在最新裝置上執行應用時,您可能會遇到 UI 被螢幕上的缺口(如劉海屏、攝像頭孔)遮擋的情況。您可以使用 SafeArea 元件來解決此問題。它會為其子元件新增內邊距(inset),以避開這些侵入性區域,同時也能避開作業系統 UI(如 Android 上的狀態列)或物理顯示屏的圓角。
如果您不需要這種行為,SafeArea 元件允許您停用四個邊中任意一邊的內邊距。預設情況下,四個邊都已啟用。
通常建議將 Scaffold 元件的 body 包裹在 SafeArea 中作為起步,但並不總是需要將其放在元件樹中如此高的位置。
例如,如果您有意讓應用延伸到缺口下方,您可以將 SafeArea 移動到僅包裹特定的相關內容,並讓應用的其餘部分全屏顯示。
使用 SafeArea 可以確保您的應用內容不會被物理顯示特徵或作業系統 UI 遮擋,併為您的應用做好準備,即使未來市場出現各種形狀和樣式的新裝置,您的應用也能保持良好的顯示效果。
SafeArea 是如何用少量程式碼實現這麼多功能的呢?在後臺,它使用了 MediaQuery 物件。
MediaQuery
#正如 SafeArea 部分所討論的,MediaQuery 是建立自適應應用的強大元件。有時您會直接使用 MediaQuery,有時則會使用在後臺呼叫了 MediaQuery 的 SafeArea。
MediaQuery 提供了大量資訊,包括應用當前的視窗大小。它還公開了輔助功能設定,例如高對比度模式、文字縮放,以及使用者是否正在使用 TalkBack 或 VoiceOver 等輔助功能服務。MediaQuery 還包含有關裝置顯示特性的資訊,例如是否有鉸鏈或摺疊屏。
SafeArea 使用來自 MediaQuery 的資料來計算為其子 Widget 新增多少內邊距。具體來說,它使用了 MediaQuery 的 padding 屬性,這基本上就是顯示屏被系統 UI、螢幕缺口或狀態列遮擋的部分。
那麼,為什麼不直接使用 MediaQuery 呢?
答案是 SafeArea 做了一件巧妙的事情,使其比單純使用原始的 MediaQueryData 更具優勢。具體而言,它修改了傳遞給 SafeArea 子元件的 MediaQuery,使其看起來好像 SafeArea 所新增的內邊距並不存在。這意味著您可以巢狀使用 SafeArea,並且只有最外層的那一個會應用避開缺口和系統 UI 所需的內邊距。
隨著應用的增長和元件的遷移,如果您嵌套了多個 SafeArea,也無需擔心應用了過多的內邊距;而如果直接使用 MediaQueryData.padding,則會遇到這類問題。
您可以用 SafeArea 包裹 Scaffold 元件的 body,但不一定要把它放在元件樹中如此高的位置。SafeArea 只需要包裹那些如果被上述硬體特性遮擋會導致資訊丟失的內容即可。
例如,如果您有意讓應用延伸到缺口下方,您可以將 SafeArea 移動到僅包裹特定的相關內容,並讓應用的其餘部分全屏顯示。順便提一下,AppBar 元件預設就是這樣做的,這就是它能夠延伸到系統狀態列下方的原理。這也是為什麼建議將 Scaffold 的 body 包裹在 SafeArea 中,而不是直接包裹整個 Scaffold 的原因。
SafeArea 以通用方式確保您的應用內容不會被遮擋,即使未來市場出現各種形狀和樣式的新裝置,您的應用也能保持良好的顯示效果。