在 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 = Runnable { 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 播放器的做法。