Votre application ne doit pas passer en mode PIP dans les situations suivantes :
- Si la vidéo est arrêtée ou mise en pause.
- Si vous vous trouvez sur une autre page de l'application que celle du lecteur vidéo
Pour contrôler le moment où votre application passe en mode PIP, ajoutez une variable qui suit l'état du lecteur vidéo à l'aide d'un mutableStateOf.
Activer/Désactiver l'état selon que la vidéo est en cours de lecture ou non
Pour basculer l'état en fonction de la lecture ou non du lecteur vidéo, ajoutez un écouteur sur le lecteur vidéo. Activez ou désactivez l'état de votre variable d'état selon que le joueur joue ou non :
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Activer/Désactiver l'état selon que le lecteur est libéré ou non
Lorsque le lecteur est libéré, définissez votre variable d'état sur false :
fun releasePlayer() { shouldEnterPipMode = false }
Utiliser l'état pour définir si le mode PIP est activé (versions antérieures à Android 12)
- Étant donné que l'ajout de PiP avant Android 12 utilise un
DisposableEffect, vous devez créer une variable enrememberUpdatedStateavecnewValuedéfini comme variable d'état. Cela garantit que la version mise à jour est utilisée dans leDisposableEffect. Dans le lambda qui définit le comportement lorsque
OnUserLeaveHintListenerest déclenché, ajoutez une instructionifavec la variable d'état autour de l'appel àenterPictureInPictureMode():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") }
Utiliser l'état pour définir si le mode PiP est activé (après Android 12)
Transmettez votre variable d'état à setAutoEnterEnabled afin que votre application ne passe en mode PIP qu'au bon moment :
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)
Utiliser setSourceRectHint pour une animation fluide
L'API setSourceRectHint crée une animation plus fluide pour passer en mode PIP. Sous Android 12 ou version ultérieure, cela crée également une animation plus fluide pour quitter le mode PIP.
Ajoutez cette API au compilateur Picture-in-picture pour indiquer la zone de l'activité visible après la transition vers le mode Picture-in-picture.
- N'ajoutez
setSourceRectHint()àbuilderque si l'état définit que l'application doit passer en mode PIP. Cela évite de calculersourceRectlorsque l'application n'a pas besoin de passer en mode PIP. - Pour définir la valeur
sourceRect, utilisez leslayoutCoordinatesfournis par la fonctiononGloballyPositionedsur le modificateur. - Appelez
setSourceRectHint()surbuilderet transmettez 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)