視窗管理

ChromeOS 支援在多個視窗中執行 Android 應用程式。系統會將應用程式算繪到視窗容器中,容器大小取決於裝置的外型規格,如圖 1 所示。

不同裝置上的應用程式視窗。
圖 1.:Caption goes here.

圖 1. 不同裝置上的應用程式視窗。

設計版面配置時,請務必考量不同螢幕尺寸。如果您遵循 Android 指南支援不同螢幕大小,應用程式在 ChromeOS 上執行時也能順利運作。

本頁面說明如何協助應用程式視窗正確啟動、順暢調整大小,以及在大小變更時顯示所有內容。

初始啟動大小

應用程式可以透過下列方式要求初始啟動大小:

  • 啟動大小僅適用於電腦環境。 這有助於視窗管理員提供適當的界線和方向。如要在電腦模式下指出偏好設定,請在 <activity> 內新增下列中繼標記:

    &lt;meta-data android:name=&#34;WindowManagerPreference:FreeformWindowSize&#34;
               android:value=&#34;[phone|tablet|maximize]&#34; /&gt;
    &lt;meta-data android:name=&#34;WindowManagerPreference:FreeformWindowOrientation&#34;
               android:value=&#34;[portrait|landscape]&#34; /&gt;
    
  • 使用靜態啟動界線。在活動的資訊清單項目中使用 <layout> 指定「固定」起始大小,如下列範例所示:

    &lt;layout android:defaultHeight=&#34;500dp&#34;
                android:defaultWidth=&#34;600dp&#34;
                android:gravity=&#34;top|end&#34;
                android:minHeight=&#34;450dp&#34;
                android:minWidth=&#34;300dp&#34; /&gt;
    
  • 使用動態啟動界線。活動可以建立及使用 ActivityOptions.setLaunchBounds(Rect),指定空白矩形即可將應用程式最大化。

調整視窗大小

在 ChromeOS 中,使用者可以照常調整應用程式視窗大小:拖曳右下角,如圖 2 所示。

圖 2.:Caption goes here.

圖 2. 可調整大小的應用程式視窗。

使用 View 類別時,處理視窗大小調整作業的方法有兩種:

  • 呼叫 onConfigurationChanged(..),動態回應設定變更。舉例來說,您可以在活動的資訊清單中加入 android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"。如要進一步瞭解如何處理設定變更,請參閱「處理設定變更」。
  • 讓系統重新啟動活動。在這種情況下,請實作 onSaveInstanceState,並使用 ViewModel 架構元件還原先前儲存的狀態。

使用 Jetpack Compose 時,縮放行為取決於活動的設定方式。如果動態處理變更,視窗大小變更時就會觸發重組。如果系統重新啟動活動,則會在重新啟動後進行初始組合。無論如何,請務必建立可配合視窗大小變更的 Compose 版面配置。請勿假設固定大小。

視窗尺寸

讓活動在每次啟動時讀取視窗尺寸,並根據目前的設定排列內容。

如要判斷目前的設定,請在目前的活動中呼叫 getResources().getConfiguration()。請勿使用背景活動或系統資源的設定。背景活動沒有大小,且系統設定可能包含多個大小和方向衝突的視窗,因此無法擷取可用資料。

請注意,視窗大小和螢幕大小並不相同。如要取得以 DP 為單位的視窗大小,請使用 Activity.getResources().getConfiguration().screenWidthActivity.getResources().getConfiguration().screenHeight。您可能永遠不需要使用螢幕尺寸。

內容界線

視窗大小調整後,內容界線可能會變更。舉例來說,如果視窗過大而無法完整顯示在螢幕上,應用程式使用的視窗區域可能會變更。請遵守下列規範:

  • 使用 Android 版面配置程序的應用程式會自動在可用空間中配置。
  • 原生應用程式需要讀取可用區域並監控大小變化,以免 UI 元素無法存取。呼叫下列方法,判斷這個介面的初始可用大小:

    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()

    您可以使用觀察器持續監控:

    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • view.addOnLayoutChangeListener(findViewById(android.R.id.content)) 新增監聽器

    如果應用程式會預先縮放圖片,請在每次解析度變更時執行這項操作。

任意形式調整大小

ChromeOS 允許任意調整視窗大小:使用者可以變更視窗的寬度、高度和在畫面上的位置。許多 Android 應用程式的編寫方式並未考量任意形式的大小調整功能。請考量下列問題:

  • 螢幕位置可能會變更。請一律使用系統執行視窗到螢幕,以及螢幕到視窗的座標轉換。
  • 如果您使用 Android 的檢視區塊系統,視窗大小變更時,視窗版面配置會自動變更。
  • 如果您未使用檢視區塊系統並接管介面,應用程式就必須自行處理大小變更。
  • 如果是原生應用程式,請使用 mLastContent 成員或內容檢視畫面,判斷初始大小。
  • 應用程式執行時,請監聽 onContentRectChangedNativeonGlobalLayout 事件,對大小變更做出反應。
  • 應用程式大小變更時,重新調整或重新載入版面配置和插圖,並更新輸入區域。

全螢幕模式

全螢幕模式的運作方式與 Android 原生系統相同。 如果視窗未涵蓋整個螢幕,系統會忽略全螢幕要求 (隱藏所有系統 UI 元素)。應用程式最大化時,系統會執行一般全螢幕方法、版面配置和函式。這會隱藏系統 UI 元素 (視窗控制列和功能架)。

螢幕方向

Android 應用程式最常見的螢幕方向是直向,因為大多數手機都是直向握持。直向模式適合手機,但筆電和平板電腦則偏好橫向模式。為獲得最佳成效,建議您同時支援這兩種螢幕方向。

部分 Android 應用程式會假設裝置處於直向模式時,旋轉值為 Surface.ROTATION_0。這可能適用於大多數 Android 裝置。不過,當應用程式處於特定 ARC 模式時,直向的旋轉值可能不是 Surface.ROTATION_0

如要在讀取加速度計或類似感應器時取得準確的旋轉值,請使用 Display.getRotation() 方法,並相應地交換軸。

根活動和螢幕方向

Chromebook 視窗是由一疊活動視窗組成。堆疊中的每個視窗大小和方向都相同。

在電腦環境中,方向和大小突然改變會造成混淆。Chromebook 視窗管理員會避免這種情況,做法與 Android 的並排模式類似:堆疊底部的活動會控管上方所有活動的屬性。這可能會導致非預期的情況,例如直向且無法調整大小的新活動變成橫向且可調整大小。

裝置模式會影響這項設定:在平板電腦模式下,螢幕方向不會鎖定,每個視窗都會保留自己的螢幕方向,這與 Android 上的正常情況相同。

方向規範

處理方向時,請遵守下列規範:

  • 如果您只支援一種螢幕方向,請在資訊清單中加入相關資訊,讓視窗管理員在啟動應用程式前瞭解這項設定。指定方向時,請盡可能也指定感應器方向。Chromebook 通常是可轉換式裝置,應用程式倒過來會造成不良的使用者體驗。
  • 請盡量只選取一種方向。請避免在資訊清單中要求一個螢幕方向,然後稍後以程式輔助方式設定另一個螢幕方向。
  • 根據視窗大小變更螢幕方向時,請務必小心。使用者可能會卡在小型直向視窗,無法返回較大的橫向視窗。
  • Chrome 視窗控制項可讓你切換所有可用的版面配置。選擇正確的方向選項,確保使用者啟動應用程式後能看到正確的版面配置。如果應用程式同時支援直向和橫向,請盡可能將橫向設為預設方向。設定這個選項後,系統會記住各個應用程式的設定。
  • 盡量避免不必要的螢幕方向變更。舉例來說,如果活動螢幕方向為直向,但應用程式在執行階段呼叫 setRequestedOrientation(LANDSCAPE),就會導致不必要的視窗大小調整,這會讓使用者感到困擾,且如果應用程式無法處理,可能會重新啟動。建議您在資訊清單中設定一次方向,並視需要變更。

其他考量

在 ChromeOS 中使用 Android 應用程式時,請注意下列事項:

  • 請勿在活動的 onDestroy 方法中呼叫 finish()。這會導致應用程式在調整大小時關閉,且不會重新啟動。
  • 請勿使用不相容的視窗類型,例如 TYPE_KEYGUARDTYPE_APPLICATION_MEDIA
  • 快取先前分配的物件,加快活動重新啟動的速度。
  • 如不希望使用者調整應用程式大小,請在資訊清單檔案中指定 android:resizeableActivity=false
  • 測試應用程式,確保能適當處理視窗大小變化。