視窗管理

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

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

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

本頁面說明如何確保應用程式的視窗正確啟動、流暢調整大小,並在大小變更時顯示其中的所有內容。

初始啟動大小

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

  • 只在電腦環境中使用啟動大小。這有助於視窗管理員為您提供適當的邊界和方向。如要指出使用電腦版模式時的偏好設定,請在 <activity> 中新增下列中繼標記:
<meta-data android:name="WindowManagerPreference:FreeformWindowSize"
           android:value="[phone|tablet|maximize]" />
<meta-data android:name="WindowManagerPreference:FreeformWindowOrientation"
           android:value="[portrait|landscape]" />
  • 使用靜態啟動邊界。請在活動的資訊清單項目中使用 <layout> 指定「固定」的起始大小,如以下範例所示:
<layout android:defaultHeight="500dp"
            android:defaultWidth="600dp"
            android:gravity="top|end"
            android:minHeight="450dp"
            android:minWidth="300dp" />
  • 使用動態啟動邊界。活動可以在建立新活動時建立及使用 ActivityOptions.setLaunchBounds(Rect)。透過指定空白矩形,即可最大化應用程式。

調整視窗大小

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

圖 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
  • 測試應用程式,確保能妥善處理視窗大小的變更。