在以下情况下,您的应用不应进入画中画模式:
- 如果视频已停止或暂停。
- 如果您位于应用中与视频播放器不同的页面。
如需控制应用何时进入画中画模式,请添加一个使用 mutableStateOf
跟踪视频播放器状态的变量。
根据视频是否正在播放切换状态
如需根据视频播放器是否正在播放来切换状态,请在视频播放器上添加监听器。根据玩家是否正在玩游戏,切换状态变量的状态:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
根据玩家是否已释放切换状态
释放播放器时,将状态变量设置为 false
:
fun releasePlayer() { shouldEnterPipMode = false }
使用状态定义是否进入了画中画模式(Android 12 之前)
- 由于在 Android 12 之前添加 PiP 时使用的是
DisposableEffect
,因此您需要通过rememberUpdatedState
创建一个新变量,并将newValue
设置为状态变量。这可确保在DisposableEffect
中使用更新后的版本。 在用于定义
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 区域。
- 仅当状态定义应用应进入 PiP 模式时,才将
setSourceRectHint()
添加到builder
。这样可以避免在应用不需要进入 PiP 时计算sourceRect
。 - 如需设置
sourceRect
值,请使用修饰符上通过onGloballyPositioned
函数给出的layoutCoordinates
。 - 对
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)