O app não pode entrar no modo PIP nas seguintes situações:
- Se o vídeo for interrompido ou pausado.
- Se você estiver em uma página diferente do player de vídeo no app.
Para controlar quando o app entra no modo picture-in-picture, adicione uma variável que rastreie 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 no fato de o player estar reproduzindo ou não:
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 PIP foi iniciado (versões anteriores ao Android 12)
- Como a adição do PiP antes do Android 12 usa um
DisposableEffect, você precisa criar uma nova variável porrememberUpdatedStatecomnewValuedefinido como 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 ao redor 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 PiP foi ativado (pós-Android 12)
Transmita a variável de estado para setAutoEnterEnabled para que o app só entre no modo PiP 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
PIP. No Android 12 e versões mais recentes, ele também cria uma animação mais suave para sair do modo picture-in-picture.
Adicione essa API ao builder de PIP para indicar a área da atividade que fica
visível após a transição para o PIP.
- Adicione
setSourceRectHint()aobuildersomente se o estado definir que o app precisa entrar no modo PIP. Isso evita o cálculo desourceRectquando o app não precisa entrar no PiP. - Para definir o valor
sourceRect, use olayoutCoordinatesfornecido 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)