在正确的时间进入 PiP 模式

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

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

如需控制应用何时进入画中画模式,请添加一个跟踪视频播放器状态 的变量,该变量使用 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. 在 lambda 中,当 OnUserLeaveHintListener 触发时定义行为,在对 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 = Runnable {
                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 添加到画中画构建器,以指明在过渡到画中画模式后可见的 activity 区域。

  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)