適配 Android N 多窗口特性的 5 個要訣
英文原文:5 tips for preparing for Multi-Window in Android N
作者:Ian Lake, Google Android 技術推廣工程師
翻譯:Guokai Han
如果你看了 What’s New in Android N 這個視頻,你會無意中發現了多窗口支持。
使用多窗口分屏功能,能夠并排地同時看到兩個應用。你可能非常興奮,想知道這是如何做到的,于是立刻去查閱文檔,看看是什么新 API 實現了這一獨特功能。
結果卻發現并沒有出現很多新的 API 。只有少量用于定制是否完全支持多窗口的 XML 屬性以及少量用于檢查當前是否處于多窗口模式的 Activity 方法。那這個魔法到底打是哪來的?其實魔法一直都在那。
所謂的魔法就是 Android 的資源系統。資源系統中最強大的部分之一是提供替代資源(alternate resources?)的能力——基于不同條件改變大小、布局、繪制、菜單等等。
多窗口就是利用了這個資源系統 – 基于窗口大小來調整配置。除了屏幕大小,最小寬度(即寬度或高度的最小值)和朝向(orientation)也會在調整窗口大小時更新。
這引出了我們第一個要訣。
要訣1:使用正確的上下文
使用適合的上下文(Context)加載合適的資源。如果你使用 Activity 上下文處理填充布局、獲取資源等工作,這就對了。
然而,如果使用的是 Application 上下文處理 UI 相關的事情,你會發現加載的資源無法感知到多窗口。除了不會使用 Activity 主題的問題,你可能會加載了完全錯誤的資源!最好讓你的 UI 資源與 Activity 上下文在一起。
要訣2:正確地處理配置變化
使用了正確的上下文,你要確保依據窗口大小獲取正確的資源(無論之前是全屏還是兩個應用的分屏)。重新加載這些資源的過程是基于你如何處理運行時變化的。
默認情況是你的整個 activity 被銷毀然后再重建。這個過程會恢復你在 onSaveInstanceState() 方法中保存的所有狀態,以及重新加載所有資源/布局。這個特性很好,你清楚所有事情都與新的配置一致并且配置的每種類型都被處理了。
不用說你也知道,每次配置變化的處理應該快速且流暢。請確保你沒有在 onResume() 方法中做太多工作,并考慮使用 loaders 來保證配置變化時數據的連續。
你依然可以自己處理配置變化,在這種情況下你的 Activity (和 Fragment) 將收到 onConfigurationChanged() 方法回調而不是先銷毀再重建,并且你需要手工管理視圖更新,重新加載資源等工作。
要捕獲多窗口相關的配置變化,你需要在 manifest 文件中添加一個 android:configChanges 屬性,并至少設置這些值:
<activity
android:name=".MyActivity"
android:configChanges="screenSize|smallestScreenSize
|screenLayout|orientation"
/>
請確保你處理了所有可能需要變化的資源(當你自己負責處理配置變化時,這是你的責任了)。
這包括重新加載那些之前被認為是不變的資源。考慮一下你在 values 和 values-sw600dp 中設置的大小。在非多窗口環境下,你無法在運行時切換它們,因為最小寬度是不變的(它總是設備的最小寬度)。然而在多窗口環境下,你可以且必需隨著應用大小的調整而切換這些資源。
要訣3:處理所有朝向
回想下本文開頭的介紹,我們談到當窗口大小調整時朝向也會隨之改變。沒錯,即使設備處于橫屏的時候,應用也可能處于“豎屏”的朝向。
其實“豎屏”真正的意義僅僅是高度大于寬度,“橫屏”的意義是寬度大于高度。所以從這個定義來考慮,在應用調整大小時,可能會從一個朝向轉到另一個朝向就說得通了。
這也就是意味著朝向之間的轉換應該盡可能平滑。引用 material design 規范中分屏部分的描述:
改變設備的朝向不應該導致 UI 發生非預期的改變。例如,在某個分屏中(豎屏模式下)正在顯示視頻的應用,在旋轉到橫屏模式時,不應該自動進入全屏播放狀態。
注意:如果你想要你的應用在全屏狀態時(非多窗口)仍有這種類型的功能,你可以使用 inMultiWindowMode() 方法檢查你當前所處的準確狀態。
使用 android:screenOrientation 鎖定屏幕朝向也會受到多窗口的影響。對于不是針對(target為) Android N 的應用,添加 android:screenOrientation 意味著你的應用根本不支持多窗口 – 這總是會強制用戶離開多窗口模式。但在針對 Android N 的應用則稍有不同 – 在這種情況下不是不支持多窗口,而是處于多窗口模式時你在 android:screenOrientation 中設置的任何朝向都會被忽略。
請記住,無論應用是否針對 Android N,在多窗口模式下在運行時鎖定朝向的 setRequestedOrientation() 方法都是無效的。
要訣4:針對所有屏幕尺寸構建響應式 UI
朝向并非是面向分屏設計的唯一問題。多窗口是平板 UI (tablet UI) 第一次遇到被縮小到微型尺寸的情況(你有平板 UI 吧?畢竟,14億設備中的 12.5% 也是很多的設備)。
如果你已經在構建響應式 UI ,能夠適應可用的空間,手機和平板有相對類似的布局,你會發現你已經為多窗口環境做了很好的準備。作為建議,把 UI 縮小到 220dp 的寬/高,然后讓應用從這個大小擴展到全屏大小是你現在可做的事情。
構建單一的響應式布局使得應用大小調整時能夠平滑過渡
然而,如果你的手機和平板 UI 差異巨大,請不要迫使用戶在這兩者之間切換 – 而是以平板 UI 為主并想辦法縮小它。有許多響應式 UI 模式可供你參考,它們可以為用戶提供流暢的調整大小體驗 – 再次說明,這些并不需要使用 Android N 的 API。
要訣5:由其它應用啟動的 Activity 必需總是支持多窗口
在多窗口環境下,你的整個任務(task)都代表的是一個單窗口。這就是為什么如果要啟動一個顯示在(多窗口)旁邊的 activity 需要啟動一個新的任務 – 新任務才能是新窗口。
反過來也是如此,來自同一個頁面中引用的內容:
如果你在一個任務堆棧中啟動一個新的 activity,這個 activity 會替換屏幕上的當前 activity ,并且會繼承所有它的多窗口屬性。
這意味著,如果你有一個能夠被其它應用啟動的 activity ,這個 activity 會繼承調用方 activity 同樣的多窗口屬性。這些屬性包括最小尺寸。如果使用的是 startActivityForResult() ,這種情況下你的 activity 必需是同一個任務堆棧的一部分,甚至在 implicit intent 的情況下也是如此。你無法確定別人是否使用了 FLAG_ACTIVITY_NEW_TASK 。
因此,所有這些直到最小尺寸的 activity (以及由 activity 啟動的 activity)都必需支持多窗口。所以請徹底測試!
全面測試!
針對多窗口環境的最佳準備工作就是測試你的應用。即使沒有修改任何代碼,也沒有配置過 Android N SDK ,只要把現有的應用安裝到 Android N 設備或模擬器上就是很好的第一步,也是最容易做的事情。
來源:http://chinagdg.org/2016/04/5-tips-for-preparing-for-multi-window-in-android-n/