在正确的时间进入画中画模式

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

  • 如果视频已停止或暂停。
  • 如果您在应用中位于视频播放器以外的页面。

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

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

要根据视频播放器是否正在播放来切换状态,请在视频播放器上添加一个监听器。根据播放器是否正在播放来切换状态变量的状态。

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

根据播放器是否已释放切换状态

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

fun releasePlayer() {
    shouldEnterPipMode = false
}

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

  1. 由于在 Android 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")
    }

使用状态定义是否进入画中画模式(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 添加到画中画构建器中,以指示在过渡到画中画模式后活动中可见的区域。

  1. 仅当状态定义应用应进入画中画模式时,才将 setSourceRectHint() 添加到 builder。这可以避免在应用不需要进入画中画时计算 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)