Android 手持裝置的子母畫面 (PIP) 功能可讓使用者將正在執行活動的應用程式調整為小型視窗。子母畫面模式對影片應用程式特別實用,因為使用者可在內容持續播放的同時執行其他動作。使用者可以透過 SystemUI 操控這個視窗的位置,並透過應用程式提供的動作 (最多三個) 與目前處於子母畫面模式的應用程式互動。
PIP 需要支援的應用程式明確選擇加入,且以個別活動為基礎運作。(單一應用程式可以有多個活動,但只有一個活動會在 PIP 中顯示。)活動會透過呼叫 enterPictureInPictureMode()
要求進入子母畫面模式,並以 onPictureInPictureModeChanged()
的形式接收活動回呼。
setPictureInPictureParams()
方法可讓活動在子母畫面和自訂動作中控制顯示比例,讓使用者不必展開活動,即可與活動互動。在子母畫面模式中,活動處於暫停但仍在算繪的狀態,且不會直接接收觸控輸入或視窗焦點。一次只能在 PIP 中顯示一個工作。
詳情請參閱 Android 開發人員的「子母畫面」說明文件。
裝置需求
如要支援 PIP,請在 /android/frameworks/base/core/java/android/content/pm/PackageManager.java
中啟用 PackageManager#FEATURE_PICTURE_IN_PICTURE
系統功能。支援 PIP 的裝置螢幕最小寬度必須大於 220 dp。與分割畫面多視窗類似,PIP 可讓多個活動同時在畫面上執行。因此,裝置應具備足夠的 CPU 和 RAM,才能支援此用途。
實作
大部分的活動生命週期管理作業都是在 ActivityManager
和 WindowManager
之間的系統中完成。參考 UI 實作項目位於 SystemUI
套件中。
系統的修改內容不應影響其內在行為,也就是 Compatibility Test Suite (CTS) 測試所定義的行為。PIP 的系統邏輯主要圍繞「已固定」堆疊中的任務和活動管理。以下簡要介紹課程:
ActivityRecord
:追蹤每個活動的子母畫面狀態。如要防止使用者在特定情況下 (例如從螢幕鎖定畫面或在 VR 期間) 進入 PIP 模式,請新增checkEnterPictureInPictureState()
的情況。ActivityManagerService
:活動的主要介面,用於要求進入子母畫面模式,以及用於呼叫WindowManager
和SystemUI
以變更子母畫面活動狀態的介面。ActivityStackSupervisor
:從ActivityManagerService
呼叫,用於將工作移入或移出已固定的堆疊,並視需要更新WindowManager
。PinnedStackWindowController
:來自ActivityManager
的WindowManager
介面。PinnedStackController
:將系統中的變更項目回報給SystemUI
,例如顯示/隱藏 IME、顯示比例變更或動作變更。BoundsAnimationController
:以不會在調整大小時觸發設定變更的方式,為 PIP 活動視窗製作動畫。PipSnapAlgorithm
:在系統和 SystemUI 中都使用的共用類別,用於控制 PIP 視窗靠近螢幕邊緣時的固定行為。
參考資料 SystemUI
提供完整的 PIP 實作,可向使用者呈現自訂動作和一般操作,例如展開和關閉。只要這些變更不會影響 CDD 定義的內在行為,裝置製造商就可以根據這些變更進行建構。以下簡要介紹課程:
PipManager
:開頭為SystemUI
的SystemUI
元件。PipTouchHandler
:觸控處理常式,可控制操控 PIP 的手勢。這個方法只會在 PIP 的輸入消費者處於活動狀態時使用 (請參閱InputConsumerController
)。您可以在此新增手勢。PipMotionHelper
:方便的類別,可追蹤 PIP 位置和螢幕上的可用區域。透過呼叫ActivityManagerService
更新或為子母畫面設定動畫效果的大小和位置。PipMenuActivityController
:啟動顯示目前 PIP 中活動提供的動作的活動。這個活動是工作重疊活動,會移除重疊的輸入用戶端,以便進行互動。PipMenuActivity
:實作選單活動。PipMediaController
:當媒體工作階段的變更可能影響 PIP 的預設動作時,會更新SystemUI
的監聽器。PipNotificationController
:可確保使用者使用 PIP 功能時,通知處於啟用狀態的控制器。PipDismissViewController
:當使用者開始與 PIP 互動時,系統會向使用者顯示疊加層,表示可以關閉 PIP。
預設刊登位置
有多種系統資源可控制 PIP 的預設位置:
config_defaultPictureInPictureGravity
:gravity 整數,用於控制要放置 PIP 的角落,例如BOTTOM|RIGHT
。config_defaultPictureInPictureScreenEdgeInsets
:從螢幕兩側放置 PIP 的偏移量。config_pictureInPictureDefaultSizePercent
和config_pictureInPictureDefaultAspectRatio
:螢幕寬度百分比和顯示比例的組合會控制 PIP 的大小。計算的預設 PIP 大小不得小於 CTS 和 CDD 定義的@dimen/default_minimal_size_pip_resizable_task
。config_pictureInPictureSnapMode
:在PipSnapAlgorithm
中定義的對齊行為。
裝置實作方式不應變更 CDD 和 CTS 中定義的最小和最大顯示比例。
權限
AppOpsManager
(main/core/java/android/app/AppOpsManager.java
) 中的個別套件「應用程式作業」(OP_PICTURE_IN_PICTURE
) 可讓使用者透過系統設定,在個別應用程式層級控制 PIP。當活動要求進入子母畫面模式時,裝置實作項目必須遵守這項檢查。
測試
如要測試 PIP 實作,請在 /cts/hostsidetests/services/activitymanager
下執行主機端 CTS 測試中的所有畫中畫相關測試,特別是 ActivityManagerPinnedStackTests.java
。