Tu app no debería ingresar al modo PIP en las siguientes situaciones:
- Si el video se detiene o se pausa
- Si estás en una página de la app diferente de la del reproductor de video
Para controlar cuándo tu app ingresa al modo 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 en el reproductor de video. 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 libere el reproductor, establece la variable de estado en false:
fun releasePlayer() { shouldEnterPipMode = false }
Usa el estado para definir si se ingresa al modo de pantalla en pantalla (anterior a Android 12)
- Como agregar PiP antes de la versión 12 usa un
DisposableEffect, debes crear una variable nueva porrememberUpdatedStateconnewValueconfigurada como tu variable de estado. Esto garantizará que se use la versión actualizada en elDisposableEffect. En la expresión lambda que define el comportamiento cuando se activa
OnUserLeaveHintListener, agrega una sentenciaifcon 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 = 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") }
Usa el estado para definir si se ingresa al modo de PIP (posterior a Android 12)
Pasa tu variable de estado a setAutoEnterEnabled para que tu app solo ingrese al modo de 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 obtener una animación fluida
La API de setSourceRectHint crea una animación más fluida para ingresar al modo de PIP. En Android 12 y versiones posteriores, también se crea una animación más fluida para salir del modo de PIP.
Agrega esta API al compilador de pantalla en pantalla para indicar el área de la actividad que es visible después de la transición a pantalla en pantalla.
- Solo agrega
setSourceRectHint()abuildersi el estado define que la app debe ingresar al modo de pantalla en pantalla. Esto evita calcularsourceRectcuando la app no necesita ingresar a PiP. - Para establecer el valor
sourceRect, usa loslayoutCoordinatesque se proporcionan desde la funciónonGloballyPositioneden el modificador. - Llama a
setSourceRectHint()enbuildery 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)