Android O ——— 畫中畫模式(PIP)初步使用總結(jié)

Android O 允許以畫中畫 (PIP) 模式啟動操作組件。PIP 是一種特殊的多窗口模式,最常用于視頻播放。目前,PIP 模式可用于 Android TV,而 Android O 則讓該功能可進(jìn)一步用于其他 Android 設(shè)備。

當(dāng)某個 Activity 處于 PIP 模式時,它會處于暫停狀態(tài),但仍應(yīng)繼續(xù)顯示內(nèi)容。因此,您應(yīng)確保您的應(yīng)用在 onPause() 處理程序中進(jìn)行處理時不會暫停播放。相反,您應(yīng)在 onStop() 中暫停播放視頻,并在 onStart() 中繼續(xù)播放。如需了解詳細(xì)信息,請參閱多窗口生命周期。

要指定您的 Activity 可以使用 PIP 模式,請在清單中將 android:supportsPictureInPicture 設(shè)置為 true。(從 Android O 開始,如果您打算在 Android TV 或其他 Android 設(shè)備上支持 PIP 模式,則無需將 android:resizeableActivity 設(shè)置為 true;只有在您的 Activity 支持其他多窗口模式時,才需要設(shè)置 android:resizeableActivity。)

多窗口生命周期

多窗口模式不會更改 Activity 生命周期

在多窗口模式中,在指定時間只有最近與用戶交互過的 Activity 為活動狀態(tài)。 該 Activity 將被視為頂級 Activity。 所有其他 Activity 雖然可見,但均處于暫停狀態(tài)。 但是,這些已暫停但可見的 Activity 在系統(tǒng)中享有比不可見 Activity 更高的優(yōu)先級。 如果用戶與其中一個暫停的 Activity 交互,該 Activity 將恢復(fù),而之前的頂級 Activity 將暫停。

注:在多窗口模式中,用戶仍可以看到處于暫停狀態(tài)的應(yīng)用。 應(yīng)用在暫停狀態(tài)下可能仍需要繼續(xù)其操作。 例如,處于暫停模式但可見的視頻播放應(yīng)用應(yīng)繼續(xù)顯示視頻。 因此,我們建議播放視頻的 Activity 不要暫停其 onPause() 處理程序中的視頻。 應(yīng)暫停 onStop() 中的視頻,并恢復(fù)onStart() 中的視頻播放。

API 變更

Android O 引入一種新的對象 PictureInPictureParams,您可以將該對象傳遞給 PIP 函數(shù)來指定某個 Activity 在其處于 PIP 模式時的行為。此對象還指定了各種屬性,例如操作組件的首選縱橫比。

現(xiàn)在,在添加畫中畫中介紹的現(xiàn)有 PIP 函數(shù)可用于所有 Android 設(shè)備,而不僅限于 Android TV。此外,Android O 還提供以下函數(shù)來支持 PIP 模式:

Activity.enterPictureInPictureMode(PictureInPictureParams args):將操作組件置于畫中畫模式。操作組件的縱橫比和其他配置設(shè)置均由 args 指定。如果 args 中的任何字段為空,系統(tǒng)將使用您上次調(diào)用 Activity.setPictureInPictureParams()時所設(shè)置的值。
指定的操作組件被置于屏幕的一角,屏幕剩余部分則被屏幕顯示的上一個操作組件填滿。進(jìn)入 PIP 模式的 Activity 將進(jìn)入暫停狀態(tài),但仍保持已啟動狀態(tài)。如果用戶點按此 PIP 操作組件,系統(tǒng)將顯示一個菜單供用戶操作,而在操作組件處于 PIP 狀態(tài)期間,不會理會任何觸摸事件。

Activity.setPictureInPictureParams():更新操作組件的 PIP 配置設(shè)置。如果操作組件目前處于 PIP 模式,則會更新此設(shè)置;如果操作組件的縱橫比發(fā)生變化,這非常有用。如果操作組件不處于 PIP 模式,則會使用這些配置設(shè)置,而不會考慮您調(diào)用的 enterPictureInPictureMode() 函數(shù)。

畫中畫 Demo示例

您的應(yīng)用可以決定何時觸發(fā) PIP 模式。以下是一些關(guān)于何時進(jìn)入 PIP 模式的示例:

  1. 當(dāng)用戶從視頻返回瀏覽其他內(nèi)容時,應(yīng)用將自動進(jìn)入 PIP 模式。
  2. 當(dāng)用戶快看完一集視頻時,應(yīng)用將視頻切換到 PIP 模式。
  3. 主屏幕顯示有關(guān)該系列視頻下一集的宣傳或摘要信息。
  4. 應(yīng)用將允許用戶在觀看視頻的同時添加其他內(nèi)容到隊列。 視頻繼續(xù)在 PIP 模式中播放,同時主屏幕顯示內(nèi)容選擇 Activity。

PIP 窗口為 240x135 dp,在屏幕角落的最頂層顯示,由系統(tǒng)在四個角落中選擇一個角落。 用戶可以調(diào)出 PIP 菜單,將 PIP 窗口切換為全屏,或通過按下遙控器上的主頁按鈕關(guān)閉 PIP 窗口。 如果主屏幕開始播放另一個視頻,PIP 窗口將自動關(guān)閉。 用戶還可以通過“最近使用記錄”關(guān)閉 PIP 窗口。

圖 1. 用戶在主屏幕上瀏覽內(nèi)容時屏幕角落窗口播放畫中畫視頻。
圖 1. 用戶在主屏幕上瀏覽內(nèi)容時屏幕角落窗口播放畫中畫視頻。

PIP 利用 Android N 中提供的多窗口 API 顯示固定視頻層疊窗口。 如需將 PIP 添加到應(yīng)用,您需要注冊支持 PIP 的 Activity,然后根據(jù)需要將 Activity 切換到 PIP 模式,并確保隱藏所有 UI 元素,且 Activity 處于 PIP 模式時視頻繼續(xù)播放。

聲明您的 Activity 支持畫中畫

默認(rèn)情況下,系統(tǒng)并不自動為應(yīng)用提供 PIP 支持。如果想要應(yīng)用支持 PIP,請將 android:supportsPictureInPicture 和 android:resizeableActivity 設(shè)置為 true,在清單中注冊視頻 Activity。 此外,應(yīng)明確指定 Activity 處理布局配置變更,這樣,在 PIP 模式過渡期間發(fā)生布局變更時,Activity 不會重新啟動。

<activity android:name="VideoActivity"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:configChanges=
    "screenSize|smallestScreenSize|screenLayout|orientation"
...

在注冊 Activity 時,請記住,在 PIP 模式中,您的 Activity 在電視屏幕上的小層疊窗口中顯示。 視頻播放 Activity 結(jié)合以盡量小的 UI 可以實現(xiàn)最佳用戶體驗。 在切換到 PIP 模式后,UI 元素較小的 Activity 帶來的用戶體驗可能較差,因為用戶在 PIP 窗口中看不到 UI 元素的詳細(xì)信息。

將您的 Activity 切換到畫中畫模式

在需要將 Activity 切換到 PIP 模式時,請調(diào)用 Activity.enterPictureInPictureMode()。在下面的示例中,當(dāng)用戶選擇媒體控制欄上的專用 PIP 按鈕時,系統(tǒng)切換到 PIP 模式:

@Override
public void onActionClicked(Action action) {
if (action.getId() == R.id.lb_control_picture_in_picture) {
    getActivity().enterPictureInPictureMode();
    return;
}
...

在媒體控制欄上添加 PIP 按鈕可以方便用戶在控制視頻播放的同時切換到 PIP 模式。

圖 1. 媒體控制欄上的畫中畫按鈕。
圖 1. 媒體控制欄上的畫中畫按鈕。

Android N 中包含一個新的 PlaybackControlsRow.PictureInPictureAction 類,它可以定義控制欄 PIP 操作并使用 PIP 圖標(biāo)。

處理畫中畫模式中的 UI

在 Activity 進(jìn)入 PIP 模式時,Activity 應(yīng)僅顯示視頻播放。 在 Activity 進(jìn)入 PIP 模式前刪除 UI 元素,當(dāng) Activity 再次全屏顯示時恢復(fù)這些元素。重寫 Activity.onPictureInPictureModeChanged() 或 Fragment.onPictureInPictureModeChanged(),并根據(jù)需要啟用或禁用 UI 元素,例如:

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    if (isInPictureInPictureMode) {
         // Hide the controls in picture-in-picture mode.
          ...
    } else {
        // Restore the playback UI based on the playback status.
          ...
     }
}

在畫中畫模式中繼續(xù)視頻播放

在 Activity 切換到 PIP 模式時,系統(tǒng)會認(rèn)為 Activity 處于暫停狀態(tài),并調(diào)用 Activity 的 onPause() 方法。 如果 Activity 因為 PIP 模式暫停,視頻播放不應(yīng)暫停,而是應(yīng)繼續(xù)播放。 在 Activity 的 onPause() 方法中檢查 PIP,并對播放做相應(yīng)處理,例如:

@Override
public void onPause() {
     // If called while in PIP mode, do not pause playback
    if (isInPictureInPictureMode()) {
         // Continue playback
          ...
     }
    // If paused but not in PIP, pause playback if necessary
    ...
  }

當(dāng) Activity 退出 PIP 模式并回到全屏模式時,系統(tǒng)會恢復(fù) Activity 并調(diào)用 onResume() 方法。

使用畫中畫的單次播放 Activity

在您的應(yīng)用中,用戶可以在瀏覽主屏幕中的內(nèi)容時選擇一個新的視頻,視頻播放 Activity 處于 PIP 模式。 在現(xiàn)有播放 Activity 中全屏模式下播放新視頻,而不是啟用可能使用戶感到困惑的新 Activity。

若要確保視頻播放請求使用的是單個 Activity 并根據(jù)需要進(jìn)入或退出 PIP 模式,在您的清單中將 Activity 的 android:launchMode 設(shè)置為 singleTask:

<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...

在您的 Activity 中,替換 Activity.onNewIntent(),處理新視頻,如果需要,停止任何現(xiàn)有視頻播放。

最佳做法

PIP 用于全屏播放視頻的 Activity。在 Activity 切換到 PIP 模式時,應(yīng)避免顯示除視頻外的其他內(nèi)容。根據(jù)處理畫中畫模式中的 UI 中所述,在 Activity 進(jìn)入 PIP 模式時進(jìn)行跟蹤,并隱藏 UI 元素。

由于 PIP 窗口懸浮在屏幕的角落,因此應(yīng)避免在主窗口被 PIP 窗口遮擋的任何區(qū)域顯示重要信息。

當(dāng) Activity 處于 PIP 模式時,其默認(rèn)不獲取輸入焦點。要在 PIP 模式中接收輸入事件,請使用 MediaSession.setMediaButtonReceiver()。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容