Inserire il PiP nei momenti corretti

L'app non deve attivare la modalità PIP nelle seguenti situazioni:

  • Se il video viene 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.

Attiva/disattiva lo stato in base alla riproduzione del video

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

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

Attiva/disattiva lo stato in base al rilascio del player

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

fun releasePlayer() {
    shouldEnterPipMode = false
}

Utilizza lo stato per definire se viene attivata la modalità PIP (pre-Android 12)

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

Utilizza lo stato per definire se viene attivata la modalità PIP (post-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)

Utilizza setSourceRectHint per un'animazione fluida

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

  1. Aggiungi setSourceRectHint() a builder solo se lo stato definisce che l'app deve attivare la modalità PiP. In questo modo eviti di calcolare sourceRect quando l'app non deve attivare la modalità PIP.
  2. Per impostare il valore sourceRect, utilizza i layoutCoordinates forniti dalla funzione onGloballyPositioned sul modificatore.
  3. Chiama setSourceRectHint() su builder e trasmetti 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)