Tu app no debe ingresar al modo PiP en las siguientes situaciones:
- Si el video está detenido o pausado
- Si estás en una página de la app diferente del reproductor de video.
Para controlar cuándo tu app ingresa en el modo de PIP, agrega una variable que haga un seguimiento del estado del reproductor de video con un mutableStateOf
.
Activa o desactiva el estado según si se está reproduciendo el video
Para activar o desactivar el estado según si el reproductor de video está reproduciendo contenido, agrega un objeto de escucha al reproductor. Activa o desactiva el estado de tu variable de estado según si el jugador está jugando o no:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Activa o desactiva el estado según si se libera el reproductor
Cuando se lance el reproductor, establece la variable de estado en false
:
fun releasePlayer() { shouldEnterPipMode = false }
Usa el estado para definir si se ingresó al modo PiP (anterior a Android 12)
- Dado que agregar PiP anterior a la versión 12 usa un
DisposableEffect
, debes crear una variable nueva conrememberUpdatedState
connewValue
establecida como tu variable de estado. Esto garantizará que se use la versión actualizada enDisposableEffect
. En la lambda que define el comportamiento cuando se activa
OnUserLeaveHintListener
, agrega una sentenciaif
con la variable de estado alrededor de la llamada aenterPictureInPictureMode()
: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") }
Usa el estado para definir si se ingresó al modo PiP (después de Android 12)
Pasa tu variable de estado a setAutoEnterEnabled
para que tu app solo entre en el modo PIP en el momento adecuado:
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)
Usa setSourceRectHint
para implementar una animación fluida
La API de setSourceRectHint
crea una animación más fluida para ingresar al modo PiP. En Android 12 y versiones posteriores, también crea una animación más fluida para salir del modo de PiP.
Agrega esta API al compilador de PiP para indicar el área de la actividad que es visible después de la transición a PiP.
- Agrega
setSourceRectHint()
solo abuilder
si el estado define que la app debe ingresar al modo PiP. Esto evita calcularsourceRect
cuando la app no necesita ingresar a PiP. - Para establecer el valor
sourceRect
, usa ellayoutCoordinates
que se proporciona desde la funciónonGloballyPositioned
en el modificador. - Llama a
setSourceRectHint()
en elbuilder
y pasa la variablesourceRect
.
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)