Inserire il PiP nei momenti corretti

L'app non deve entrare in modalità PiP nelle seguenti situazioni:

  • Se il video è stato interrotto o messo in pausa.
  • Se ti trovi in una pagina dell'app diversa dal video player.

Per controllare quando l'app entra in modalità PiP, aggiungi una variabile che monitora lo stato del video player utilizzando un mutableStateOf.

Attivare/disattivare lo stato in base alla riproduzione del video

Per attivare/disattivare lo stato in base alla riproduzione del video player, aggiungi un listener al video player. Attiva/disattiva lo stato della variabile di stato in base alla riproduzione o meno del player:

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

Attivare/disattivare lo stato in base al rilascio del player

Quando il player viene rilasciato, imposta la variabile di stato su false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

Utilizzare lo stato per definire se la modalità PiP è stata attivata (prima di Android 12)

  1. Poiché l'aggiunta di PiP prima di Android 12 utilizza un DisposableEffect, devi creare una nuova variabile con rememberUpdatedState e impostare newValue come variabile di stato. In questo modo, la versione aggiornata verrà utilizzata all'interno di DisposableEffect.
  2. Nella lambda che definisce il comportamento quando viene attivato OnUserLeaveHintListener, aggiungi un'istruzione if con la variabile di stato intorno alla chiamata a 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")
    }

Utilizzare lo stato per definire se la modalità PiP è stata attivata (dopo Android 12)

Passa la variabile di stato a setAutoEnterEnabled in modo che l'app entri in modalità PiP solo al momento giusto:

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)

Utilizzare setSourceRectHint per un'animazione fluida

L'API setSourceRectHint crea un'animazione più fluida per l'attivazione della modalità PiP. Su Android 12 e versioni successive, crea anche un'animazione più fluida per la disattivazione della modalità PiP. Aggiungi questa API al builder PiP per indicare l'area dell'attività visibile dopo la transizione a PiP.

  1. Aggiungi setSourceRectHint() al builder solo se lo stato definisce che l'app deve entrare in modalità PiP. In questo modo, eviti di calcolare sourceRect quando l'app non deve entrare in modalità PiP.
  2. Per impostare il valore di sourceRect, utilizza layoutCoordinates fornito dalla funzione onGloballyPositioned nel modificatore.
  3. Chiama setSourceRectHint() nel builder e passa la variabile 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)