O app não deve entrar no modo picture-in-picture nas seguintes situações:
- Se o vídeo estiver parado ou pausado.
- Se você estiver em uma página do app diferente do player de vídeo.
Para controlar quando o app entra no modo picture-in-picture, adicione uma variável que rastreia o estado
do player de vídeo usando um mutableStateOf.
Alternar o estado com base na reprodução do vídeo
Para alternar o estado com base na reprodução do player de vídeo, adicione um listener ao player. Alterne o estado da variável de estado com base na reprodução do player:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Alternar o estado com base na liberação do player
Quando o player for liberado, defina a variável de estado como false:
fun releasePlayer() { shouldEnterPipMode = false }
Usar o estado para definir se o modo picture-in-picture será ativado (antes do Android 12)
- Como a adição do picture-in-picture antes do Android 12 usa um
DisposableEffect, é necessário criar uma nova variável porrememberUpdatedStatecomnewValuedefinido como a sua variável de estado. Isso garante que a versão atualizada seja usada noDisposableEffect. Na lambda que define o comportamento quando o
OnUserLeaveHintListeneré acionado, adicione uma instruçãoifcom a variável de estado em torno da chamada paraenterPictureInPictureMode():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") }
Usar o estado para definir se o modo picture-in-picture será ativado (depois do Android 12)
Transmita a variável de estado para setAutoEnterEnabled para que o app só entre no modo picture-in-picture no momento certo:
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)
Usar setSourceRectHint para uma animação suave
A API setSourceRectHint cria uma animação mais suave para entrar no modo picture-in-picture. No Android 12 e versões mais recentes, ela também cria uma animação mais suave para sair do modo picture-in-picture.
Adicione essa API ao builder do picture-in-picture para indicar a área da atividade que fica visível após a transição para o modo picture-in-picture.
- Só adicione
setSourceRectHint()aobuilderse o estado definir que o app precisa entrar no modo picture-in-picture. Isso evita o cálculo desourceRectquando o app não precisa entrar no modo picture-in-picture. - Para definir o valor
sourceRect, use aslayoutCoordinatesfornecidas pela funçãoonGloballyPositionedno modificador. - Chame
setSourceRectHint()nobuildere transmita a variávelsourceRect.
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)