在正確時間輸入 PiP

在下列情況下,應用程式不應進入子母畫面模式:

  • 影片是否已停止或暫停播放。
  • 如果你目前位於應用程式的其他頁面,而非影片播放器。

如要控制應用程式進入子母畫面模式的時機,請使用 mutableStateOf 新增變數,以便追蹤影片播放器的狀態。

根據影片播放狀態切換狀態

如要根據影片播放器是否正在播放來切換狀態,請在影片播放器上新增事件監聽器。根據玩家是否播放,切換狀態變數的狀態:

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

根據玩家是否已釋出來切換狀態

當玩家釋放時,請將狀態變數設為 false

fun releasePlayer() {
    shouldEnterPipMode = false
}

使用狀態定義是否進入 PiP 模式 (Android 12 以下版本)

  1. 由於新增 12 版以下的子母畫面模式會使用 DisposableEffect,因此您需要透過 rememberUpdatedState 建立新變數,並將 newValue 設為狀態變數。這可確保 DisposableEffect 使用的是更新版本。
  2. 在定義 OnUserLeaveHintListener 觸發時的行為的 lambda 中,請在 enterPictureInPictureMode() 的呼叫周圍加上狀態變數的 if 陳述式:

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    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 = {
                if (currentShouldEnterPipMode) {
                    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")
    }

使用狀態定義是否進入 PiP 模式 (Android 12 之後)

將狀態變數傳遞至 setAutoEnterEnabled,讓應用程式只在適當時間進入 PiP 模式:

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

使用 setSourceRectHint 實作流暢的動畫

setSourceRectHint API 可建立更流暢的動畫,讓您進入 PiP 模式。在 Android 12 以上版本中,它還會建立更流暢的動畫,用於退出子母畫面模式。將這個 API 新增至子母畫面建構工具,指出在轉換至子母畫面後,可見的活動區域。

  1. 只有在狀態定義應用程式應進入 PiP 模式時,才將 setSourceRectHint() 新增至 builder。這樣一來,當應用程式不需要進入 PiP 時,就不會計算 sourceRect
  2. 如要設定 sourceRect 值,請使用修飾符上 onGloballyPositioned 函式提供的 layoutCoordinates
  3. builder 呼叫 setSourceRectHint(),並傳入 sourceRect 變數。

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)