在 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 之前的版本)
如要為 Android 12 之前的版本新增子母畫面,請使用 addOnUserLeaveHintProvider。如要在 Android 12 之前的版本中新增子母畫面,請按照下列步驟操作:
- 新增版本閘道,確保只有 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 以上版本)
Android 12 之後,PictureInPictureParams.Builder會透過傳遞至應用程式影片播放器的修飾符新增。
- 建立
modifier,並對其呼叫onGloballyPositioned。版面配置座標會在後續步驟中使用。 - 建立
PictureInPictureParams.Builder()的變數。 - 新增
if陳述式,檢查 SDK 是否為 S 以上版本。如果是,請將setAutoEnterEnabled新增至建構工具,並設為true,以便在滑動時進入子母畫面模式。與透過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 設定子母畫面視窗的顯示比例
如要設定子母畫面視窗的顯示比例,你可以選擇特定顯示比例,或使用播放器影片大小的寬度和高度。如果您使用 media3 播放器,請先檢查播放器是否不為空值,以及播放器的影片大小是否不等於 VideoSize.UNKNOWN,再設定顯示比例。
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 播放器類似。