一 背景
市面上的一些視頻類應用,比如愛奇藝,嗶哩嗶哩等都有小窗功能;為了提供更好的用戶體驗,那咱也有必要對Android系統支持的畫中畫模式進行一番調研;
二 簡介
從Android 8.0(API級別26)開始,Android允許活動以畫中畫(PiP)模式啟動。PiP是一種特殊的多窗口模式,主要用于視頻播放。它允許用戶在屏幕的一個角落觀看固定大小的視頻窗口,同時在主屏幕上瀏覽內容或切換應用程序。
PiP利用Android 7.0中提供的多窗口API來提供固定的視頻覆蓋窗口。要向應用程序添加PiP功能,您需要注冊支持PiP的Activity,根據需要將活動切換到PiP模式,并確保在活動處于PiP模式時隱藏UI元素并繼續視頻播放。
PiP窗口出現在屏幕的最頂層,并在系統選擇的一個角落。
三 生命周期
進入PiP
調用enterPictureInPictureMode()方法
退出PiP
點擊小窗中的全屏按鈕
從上面的生命周期可以得出,進入或退出PiP都會引發Actvitity的銷毀和重建;如果我們想避免重建可以對confingChanges進行配置;另外Activity或Fragment的onPictureInPictureModeChanged()方法可以監聽PiP的狀態;
四 實現步驟
聲明PiP支持
默認情況下,系統不會自動為您的應用程序提供PiP支持。如果您希望在應用程序中支持PiP,可以在清單文件中注冊Activity時,將android:supportsPictureInPicture設置為true。此外,還要指定Activity的configChanges,以確保在PiP模式轉換期間發生布局更改時不會重新啟動您的Activity。
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"/>
...
判斷是否支持PiP
boolean mPipMode = getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
進入PiP
override fun onActionClicked(action: Action) {
if (action.id.toInt() == R.id.lb_control_picture_in_picture) {
activity?.enterPictureInPictureMode()
return
}
}
UI處理
當活動進入或退出PiP模式時,系統會調用Activity.onPictureInPictureModeChanged()或Fragment.onPictureInPictureModeChanged()。
您應該重寫這些回調方法來重新繪制活動的UI元素。請記住,在PiP模式下,您的活動以一個小窗口顯示。當活動處于PiP模式時,用戶無法與您的應用程序的UI元素進行交互,并且小型UI元素的細節可能難以看清。最好提供最簡化的UI的視頻播放活動,以提供最佳的用戶體驗。
如果您的應用程序需要為PiP提供自定義操作,請參閱本頁面上的“添加控件”。在您的活動進入PiP模式之前,刪除其他UI元素,并在活動恢復全屏模式時恢復它們:
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean,
newConfig: Configuration) {
if (isInPictureInPictureMode) {
// Hide the full-screen UI (controls, etc.) while in PiP mode.
} else {
// Restore the full-screen UI.
}
}
添加控件
PiP窗口可以在用戶打開窗口菜單時顯示控件(通過在移動設備上輕觸窗口或通過電視遙控器選擇菜單)。
如果應用程序具有活動媒體會話,則會顯示播放、暫停、下一個和上一個控件。
您還可以通過在進入PiP模式之前使用PictureInPictureParams.Builder.setActions()構建PictureInPictureParams來明確指定自定義操作,并在進入PiP模式時傳遞這些參數使用enterPictureInPictureMode(android.app.PictureInPictureParams)或setPictureInPictureParams(android.app.PictureInPictureParams)。
setActions方式
MediaSession方式
初始化MediaSession
自定義MediaSessionCallback,響應控件操作;
單播放Activity
在您的應用程序中,用戶在主屏幕上瀏覽內容時,可能會選擇一個新的視頻,而視頻播放活動處于PiP模式。為了避免讓用戶感到困惑,應該在現有的播放活動中以全屏模式播放新的視頻,而不是啟動一個新的活動。
為了確保單個活動用于視頻播放請求,并根據需要切換進入或退出PiP模式,請在清單文件中將活動的android:launchMode設置為singleTask:
<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...
在您的活動中,重寫onNewIntent()方法,并處理新的視頻請求,如果需要的話停止任何正在播放的現有視頻。