在 AndroidManifest.xml
檔案的活動標記中,執行下列操作:
- 新增
supportsPictureInPicture
並將其設為true
,宣告您將在應用程式中使用 PiP。 新增
configChanges
並將其設為orientation|screenLayout|screenSize|smallestScreenSize
,指定活動會處理版面配置設定變更。這樣一來,如果版面配置在子母畫面模式轉換期間有所變更,活動就不會重新啟動。<activity android:name=".SnippetsActivity" android:exported="true" android:supportsPictureInPicture="true" android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize" android:theme="@style/Theme.Snippets">
在 Compose 程式碼中執行下列操作:
- 在
Context
中新增這個擴充功能。您將在指南中多次使用這項擴充功能來存取活動。internal fun Context.findActivity(): ComponentActivity { var context = this while (context is ContextWrapper) { if (context is ComponentActivity) return context context = context.baseContext } throw IllegalStateException("Picture in picture should be called in the context of an Activity") }
在 Android 12 以下版本中新增離開應用程式時的 PiP
如要為 Android 12 以下版本新增子母畫面,請使用 addOnUserLeaveHintProvider
。如要為 Android 12 以下版本新增 PiP,請按照下列步驟操作:
- 新增版本閘道,讓這段程式碼只在 O 到 R 版本中存取。
- 使用
DisposableEffect
,並以Context
做為鍵。 - 在
DisposableEffect
中,定義使用 lambda 觸發onUserLeaveHintProvider
時的行為。在 lambda 中,對findActivity()
呼叫enterPictureInPictureMode()
,並傳入PictureInPictureParams.Builder().build()
。 - 使用
findActivity()
新增addOnUserLeaveHintListener
,並傳入 lambda。 - 在
onDispose
中,使用findActivity()
新增removeOnUserLeaveHintListener
,並傳入 lambda。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S ) { val context = LocalContext.current DisposableEffect(context) { val onUserLeaveBehavior: () -> Unit = { context.findActivity() .enterPictureInPictureMode(PictureInPictureParams.Builder().build()) } context.findActivity().addOnUserLeaveHintListener( onUserLeaveBehavior ) onDispose { context.findActivity().removeOnUserLeaveHintListener( onUserLeaveBehavior ) } } } else { Log.i("PiP info", "API does not support PiP") }
在 Android 12 之後的版本中新增離開應用程式時的 PiP
在 Android 12 之後,PictureInPictureParams.Builder
會透過傳遞至應用程式影片播放器的修飾符新增。
- 建立
modifier
,並呼叫其上的onGloballyPositioned
。稍後的步驟會使用版面配置座標。 - 為
PictureInPictureParams.Builder()
建立變數。 - 新增
if
陳述式,檢查 SDK 是否為 S 以上版本。如果是,請將setAutoEnterEnabled
新增至建構工具,並將其設為true
,以便在滑動時進入 PiP 模式。這比透過enterPictureInPictureMode
提供更流暢的動畫。 - 使用
findActivity()
呼叫setPictureInPictureParams()
。對builder
呼叫build()
,然後傳入。
val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(true) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
使用 setAspectRatio
設定子母畫面視窗的顯示比例
如要設定 PiP 視窗的顯示比例,您可以選擇特定的顯示比例,也可以使用播放器影片大小的寬度和高度。如果您使用 media3 播放器,請先確認播放器不為空值,且播放器的影片大小不等於 [VideoSize.UNKNOWN
][6],再設定顯示比例。
val context = LocalContext.current val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) { val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect() builder.setSourceRectHint(sourceRect) builder.setAspectRatio( Rational(player.videoSize.width, player.videoSize.height) ) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(shouldEnterPipMode) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
如果您使用的是自訂播放器,請使用播放器專屬的語法,設定播放器的高度和寬度的顯示比例。請注意,如果播放器在初始化期間調整大小,且超出可用的顯示比例邊界,應用程式就會當機。您可能需要新增檢查項目,以便計算顯示比例,類似於 media3 播放器的做法。