支援連接的螢幕

連線螢幕可將電腦視窗體驗延伸至標準手機,讓使用者透過行動裝置存取大螢幕。這項功能為應用程式互動和使用者生產力開創了新可能性。

外接螢幕會套用所有桌面視窗的獨特功能。將手機連上螢幕時,手機的狀態不會改變,連線的螢幕會啟動空白的桌面工作階段。裝置和螢幕會做為兩個獨立系統運作,每個螢幕都有專屬的應用程式。

圖 1. 手機連上外接螢幕,螢幕上顯示電腦工作階段,手機則維持自身狀態。

如果將支援桌面視窗功能的裝置 (例如平板電腦) 連接至外接螢幕,桌面工作階段就會同時顯示在兩個螢幕上。這時,兩部螢幕就會成為一個連續系統。完成設定後,視窗、內容和游標就能在兩個螢幕之間自由移動。

圖 2. 平板電腦連上外接螢幕,將桌面工作階段擴展到兩個螢幕上。

如要有效支援連網螢幕,必須注意應用程式設計和導入作業的幾個面向。下列最佳做法可確保使用者體驗順暢且有效率。

處理動態顯示變更

許多應用程式的建構前提是 Display 物件及其特徵在應用程式生命週期內不會變更。不過,當使用者連線或中斷連線外部螢幕,甚至在螢幕之間移動應用程式視窗時,與應用程式內容或視窗相關聯的基礎 Display 物件可能會變更。螢幕的屬性 (例如大小、解析度、刷新率、HDR 支援和密度) 可能都不相同。舉例來說,如果您根據手機螢幕硬式編碼值,版面配置可能會在外部螢幕上中斷。

外部螢幕的像素密度也可能差異極大。請務必確保應用程式能正確回應密度變化。包括在版面配置中使用密度獨立像素 (dp)、提供特定密度的資源,以及確保 UI 能適當縮放。

如果活動在外接螢幕上執行時,螢幕中斷連線,系統會將活動移至主螢幕。移動作業會觸發設定變更 (例如螢幕大小和密度變更),這可能會導致活動重新建立。應用程式必須儲存及還原 UI 狀態,以處理設定變更,避免資料遺失或造成使用者體驗混淆。

使用正確的脈絡

在多重顯示環境中,使用適當的背景至關重要。存取資源時,活動內容與應用程式內容並不相同,前者會顯示在畫面上,而後者不會。

活動內容包含螢幕的相關資訊,而且一律會根據活動顯示的螢幕區域進行調整,方便您取得應用程式的正確螢幕密度或視窗指標資訊。如需目前的視窗或螢幕資訊,請一律使用活動內容 (或其他使用者介面式內容)。這也會影響部分使用背景資訊的系統 API。

在 Jetpack Compose 中,您可以使用 CompositionLocal 物件 (例如 LocalConfiguration.currentLocalDensity.current) 存取螢幕專屬資訊。當活動或視窗在螢幕間移動時,裝置設定會變更,並觸發使用新螢幕指標的重組作業。CompositionLocal 物件可讓 UI 順暢調整。

取得螢幕資訊

您可以使用 Display 類別取得螢幕大小、密度或旗標等資訊。使用 DisplayManager 系統服務取得可用螢幕。如要找出外部螢幕,請篩除 Display.DEFAULT_DISPLAY,這通常是內建的手機或平板電腦螢幕:

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }

管理活動啟動和設定

連線螢幕可讓應用程式指定要在哪個螢幕上執行,無論是啟動時或建立其他活動時都適用。這個行為取決於資訊清單檔案中定義的活動啟動模式,以及啟動活動的實體所設定的意圖旗標和選項。

當活動移至第二螢幕時,應用程式可能會執行情境更新、調整視窗大小,以及設定和資源變更。如果活動處理了設定變更,則會在 onConfigurationChanged() 中通知活動。否則將重新啟動活動。

如果活動所選取的啟動模式允許多個執行個體,則在次要螢幕上啟動活動時,系統會建立活動的新執行個體。這兩個活動會同時恢復,在某些多工情境中相當實用。

您可以使用 ActivityOptions 在特定螢幕上啟動活動。請注意,launchDisplayId 需要 Android 8 (API 級別 26) 以上版本。

// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
    .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
    ?.displayId

// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
    val intent = Intent(this, MySecondaryActivity::class.java)
    val options = ActivityOptions.makeBasic()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.launchDisplayId = externalDisplayId
    }
    startActivity(intent, options.toBundle())
} else {
    // Optionally, handle the case where no external display is connected.
}

避免使用裝置許可清單

應用程式有時會透過允許清單或檢查 BUILD.MODEL 和內建顯示大小,將大螢幕 UI 和功能限制在特定裝置上。這種做法不適用於連線螢幕,因為幾乎任何裝置都能連線到大螢幕,而且連線外部螢幕時,裝置型號不會改變。

請在執行階段檢查視窗指標或裝置功能,做出 UI 決策,而不是使用允許清單或檢查 BUILD.MODEL 和內建螢幕大小。使用 Jetpack WindowManager API 或視窗大小類別,為各種螢幕大小和密度建構回應式和自動調整式版面配置。

支援外部周邊裝置

使用者連接外接螢幕時,通常會建立類似桌面的環境。這通常需要使用外接鍵盤、滑鼠、觸控板、網路攝影機、麥克風和喇叭。請務必確保應用程式能與這些周邊裝置順暢運作。包括處理鍵盤快速鍵、管理滑鼠指標互動、正確支援外部攝影機或麥克風,以及遵守音訊輸出路徑。詳情請參閱「大螢幕的輸入相容性」。

提高使用者工作效率

連結螢幕可大幅提升使用者工作效率。您現在可以運用這些工具,建構可提供與電腦應用程式相近體驗的行動應用程式。建議您導入下列功能,提高使用者工作效率

  • 允許使用者開啟同一應用程式的多個執行個體。這對於比較文件、管理不同對話或同時查看多個檔案等工作來說非常實用。
  • 讓使用者透過拖曳功能,在應用程式內外分享豐富的資料。
  • 實作健全的狀態管理系統,協助使用者在設定變更後維持工作流程。

只要遵循這些規範並運用提供的程式碼範例,就能建立可順暢配合連線螢幕調整的應用程式,為使用者提供更豐富且更有效率的體驗。