Activer le mode PiP au bon moment

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 le 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.

Basculer l'état en fonction de la lecture de la vidéo

Pour basculer l'état en fonction de la lecture du lecteur vidéo, ajoutez un écouteur sur le lecteur vidéo. Basculez l'état de votre variable d'état en fonction de la lecture ou non du lecteur :

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

Basculer l'état en fonction de la libération du lecteur

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é (avant Android 12)

  1. Étant donné que l'ajout de PiP avant la version 12 utilise un DisposableEffect, vous devez créer une variable à l'aide de rememberUpdatedState avec newValue défini comme variable d'état. Cela garantit que la version mise à jour est utilisée dans le DisposableEffect.
  2. Dans le lambda qui définit le comportement lorsque le OnUserLeaveHintListener est déclenché, ajoutez une instruction if avec 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. Dans Android 12 et versions ultérieures, elle crée également une animation plus fluide pour quitter le mode PiP. Ajoutez cette API au compilateur PiP pour indiquer la zone de l'activité visible après la transition vers le mode PiP.

  1. N'ajoutez setSourceRectHint() au builder que si l'état définit que l'application doit passer en mode PiP. Cela évite de calculer sourceRect lorsque l'application n'a pas besoin de passer en mode PiP.
  2. Pour définir la valeur sourceRect, utilisez les layoutCoordinates fournies par la fonction onGloballyPositioned sur le modificateur.
  3. Appelez setSourceRectHint() sur le builder et transmettez la variable sourceRect.

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)