在正确的时间进入 PiP 模式

在以下情况下,您的应用不应进入画中画模式:

  • 如果视频已停止或暂停。
  • 如果您位于应用中与视频播放器不同的页面。

如需控制应用何时进入画中画模式,请添加一个使用 mutableStateOf 跟踪视频播放器状态的变量。

根据视频是否正在播放切换状态

如需根据视频播放器是否正在播放来切换状态,请在视频播放器上添加监听器。根据玩家是否正在玩游戏,切换状态变量的状态:

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

根据玩家是否已释放切换状态

释放播放器时,将状态变量设置为 false

fun releasePlayer() {
    shouldEnterPipMode = false
}

使用状态定义是否进入了画中画模式(Android 12 之前)

  1. 由于在 Android 12 之前添加 PiP 时使用的是 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")
    }

使用状态定义是否进入了画中画模式(Android 12 之后)

将状态变量传递给 setAutoEnterEnabled,以便应用仅在适当的时间进入画中画模式:

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 可创建更流畅的进入画中画模式的动画。在 Android 12 及更高版本中,它还会为退出画中画模式创建更流畅的动画。将此 API 添加到 PiP 构建器,以指明在转换为画中画模式后可见的 activity 区域。

  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)