Jetpack WindowManager,Android 摺疊屏官方適配方案!

文章首發於公衆號: 「 技術最TOP 」,天天都有乾貨文章持續更新,能夠微信搜索 「 技術最TOP 」第一時間閱讀,回覆【思惟導圖】【面試】【簡歷】有我準備一些Android進階路線、面試指導和簡歷模板送給你

1. 前言

是的,Jetpack 又添加新成員了,那就是WindowManager,它是幹什麼用的呢?本文就帶你一塊兒瞭解一下。java

WindowManager是Android Jetpack的最新功能,旨在幫助APP開發人員支持新的設備尺寸,併爲新舊平臺版本上的各類Window Manager功能提供通用的API交互。如今,最初的版本面向可摺疊設備,未來的版本將擴展爲支持更多的顯示類型和窗口功能。android

2. 爲何咱們須要它?

如今,市場上新出了一些可摺疊屏設備,它們提供了一組獨特的硬件功能。針對這些新設備和外形來優化你的APP,能給用戶帶來不同凡響的體驗,而且讓用戶能充分利用他們所使用的設備。git

例如,三星Galaxy Z Flip是翻蓋式設備,支持摺疊和部分摺疊狀態(三星稱爲Flex模式)。當設備處於部分摺疊狀態時,該應用能夠優化其佈局,並將底部的控件與頂部的其他內容分開。如相機或者圖庫可能會以下適配:github

用戶能夠將手機放在平坦的地方(例如在桌子上),而後使用屏幕的下半部分導航和與應用交互。面試

Jetpack WindowManager 庫的目標就是,爲市面全部類型的可摺疊設備提供單一的上層API,以便開發者能夠這對不一樣類型的類型的設備進行適配,而不是爲每個設備模型都單獨適配。微信

在1.0.0版中,該庫提供了有關可摺疊設備的兩個物理屬性的信息-顯示特徵設備狀態app

  • DisplayFeature: 這個API能夠識別屏幕的表面是否連續,好比鉸鏈或者摺疊。
  • DeviceState : 這個API經過定義的狀態列表來(例如CLOSEDOPENEDHALF_OPENED等)提供手機的當前狀態。

3. 顯示特徵

單個顯示面板或多個顯示配置可能具備不一樣的特徵,這些特徵會在連續的屏幕表面產生干擾,好比摺疊鉸鏈彎曲區域劉海切口。若是應用程序窗口中存在此類中斷,則能夠調整內容在窗口中的佈局和位置,以免此類區域顯示異常,或者將它們用做天然分隔。這也能展示此類設備的優點。maven

每一個顯示特徵區均可以經過其在窗口座標空間中的邊界矩形及其類型來表徵。矩形指示了特徵的物理範圍。特徵的類型將有助於定義如何對待它。好比說,某些特徵能夠建立物理分隔和/或非交互區域(例如,兩個顯示面板之間的鉸鏈,顯示切口),而其餘特徵能夠用做邏輯分隔符(例如,摺疊)。ide

public class DisplayFeature {
    private Rect mRect;
    private @Type int mType;
    ...
}

Jetpack WindowManager 的第一個版本僅包含兩種類型的功能:TYPE_FOLDTYPE_HINGE佈局

特別對於TYPE_FOLD,邊界矩形應爲 zero-high (0, y, width, y) 或者zero-wide (x, 0, x, height),這代表沒有不可訪問的區域,可是它仍然報告屏幕上的位置。

4. 設備狀態

取決於鉸鏈硬件設計,不一樣的可摺疊設備能夠具備幾種中間狀態:關閉部分打開徹底打開(平坦表面)或翻轉

使用Jetpack WindowManager時,APP能夠根據這些設備狀態提供不一樣的功能。這些狀態定義爲不一樣的姿式:

@IntDef({
    POSTURE_UNKNOWN,
    POSTURE_CLOSED,
    POSTURE_HALF_OPENED,
    POSTURE_OPENED,
    POSTURE_FLIPPED
})
public @interface Posture{}

每一個設備能夠獲取上面定義的這些姿式的任何子集,具體取決於它們的硬件和所需的用戶體驗。

4. 如何使用?

說了這麼多,到底該如何使用呢?

別猴急~慢慢來...

首先,須要將Window Manager 的maven倉庫地址添加到項目中,在app 下面的build.gradle中添加依賴:

dependencies {
    implementation "androidx.window:window:1.0.0-alpha01"
}

如上圖所示,假設你想在可摺疊設備上拆分Google Duo等應用的用戶界面。一般,在設備的物理配置和狀態爲用戶形成邏輯隔離的狀況下,這樣作是有意義的。

例如,Galaxy Z Flip在「 Flex」或「對摺」模式下會產生這種邏輯上的分離。所以,您須要知道摺疊在應用程序窗口中的位置以及設備的狀態

首先,從Activity獲取androidx.window.WindowManager的實例。

var windowManager = WindowManager(this /* context */, null /* windowBackend */)

要注意這裏的參數

由於只有在存在邏輯硬件分離時,才分離UI,有兩種狀況:

一、 顯示特徵的類型爲TYPE_HINGE,而且活動窗口內始終存在物理分隔。

二、或者顯示特徵的類型爲Type_Fold,而且屏幕狀態不平坦(例如,不是POSTURE_OPENED)。特別是對於Galaxy Z Flip,咱們會對POSTURE_HALF_OPENED感興趣。

對於摺疊的狀況,咱們須要瞭解設備狀態變化,所以咱們須要註冊DeviceState變化監聽器:

windowManager.registerDeviceStateChangeCallback(
    mainThreadExecutor /* Executor */,
    callback /* Consumer<DeviceState> */)

在回調中,您能夠更改設備狀態並根據須要更新UI。 最後,咱們須要獲取活動窗口中的實際顯示特徵。

val displayFeatures = windowManager.windowLayoutInfo.displayFeatures

根據你的Activity處理(或不處理)配置更改的方式,你可能須要在「Activity」生命週期的不一樣時間點詢問它。而後在window decor view
的佈局上應用,以確保在Activity狀態更改後它始終是最新的。代碼以下:

window.decorView.doOnLayout {
    val displayFeatures =
        windowManager.windowLayoutInfo.displayFeatures
    ...
}

請注意,顯示特徵的位置是相對於活動窗口座標空間計算的,所以,只能在將Activity附加到窗口以後才能提供。在此以前請求信息將引起異常。

5. 最後

強烈建議運行查看官方Demo 來探索Jetpack WindowManager,它還包含了如何計算顯示特徵在View 機構中的位置的示例,還有一些示例,如在找到分割顯示特徵時自動分割佈局等等。Demo地址:https://github.com/android/user-interface-samples/tree/master/WindowManager