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 app 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 no vídeo em reprodução
Para alternar o estado com base no estado do player de vídeo, adicione um listener no player de vídeo. Alterne o estado da variável de estado com base no estado de reprodução do player:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Alternar o estado com base no lançamento do jogador
Quando o jogador for liberado, defina a variável de estado como false
:
fun releasePlayer() { shouldEnterPipMode = false }
Use o estado para definir se o modo PiP foi inserido (antes do Android 12)
- Como a adição do PiP pré-12 usa um
DisposableEffect
, é necessário criar uma nova variável comrememberUpdatedState
comnewValue
definido 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çãoif
com 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: () -> 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") }
Use o estado para definir se o modo picture-in-picture foi aberto (após o Android 12)
Transmita a variável de estado para setAutoEnterEnabled
para que o app 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)
Use setSourceRectHint
para implementar 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, ele também cria uma animação mais suave para sair do modo picture-in-picture.
Adicione essa API ao criador de PiP para indicar a área da atividade que fica
visível após a transição para o PiP.
- Adicione
setSourceRectHint()
aobuilder
somente se o estado definir que o app precisa entrar no modo PiP. Isso evita o cálculo desourceRect
quando o app não precisa entrar no PiP. - Para definir o valor
sourceRect
, use oslayoutCoordinates
fornecidos pela funçãoonGloballyPositioned
no modificador. - Chame
setSourceRectHint()
nobuilder
e 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)