PiP zur richtigen Zeit starten

In den folgenden Situationen sollte Ihre App nicht in den PiP-Modus wechseln:

  • Ob das Video gestoppt oder pausiert ist
  • Wenn du dich auf einer anderen Seite der App als dem Videoplayer befindest.

Wenn du festlegen möchtest, wann deine App in den BiB-Modus wechselt, füge eine Variable hinzu, die den Status des Videoplayers mithilfe eines mutableStateOf erfasst.

Status basierend darauf umschalten, ob das Video abgespielt wird

Wenn Sie den Status je nachdem, ob der Videoplayer gerade etwas wiedergibt, umschalten möchten, fügen Sie dem Videoplayer einen Listener hinzu. Ändern Sie den Status der Statusvariable, je nachdem, ob der Player gerade Inhalte wiedergibt oder nicht:

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

Status umschalten, je nachdem, ob der Spieler freigelassen wurde

Wenn der Player freigegeben wird, setze die Statusvariable auf false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

Mit dem Status definieren, ob der PiP-Modus aktiviert wird (vor Android 12)

  1. Da für das Hinzufügen von BiB vor Android 12 ein DisposableEffect verwendet wird, müssen Sie eine neue Variable erstellen, indem Sie rememberUpdatedState mit newValue als Statusvariable festlegen. Dadurch wird sichergestellt, dass die aktualisierte Version in der DisposableEffect verwendet wird.
  2. Fügen Sie in der Lambda-Funktion, die das Verhalten beim Auslösen von OnUserLeaveHintListener definiert, eine if-Anweisung mit der Statusvariable um den Aufruf von enterPictureInPictureMode() hinzu:

    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")
    }

Status verwenden, um zu definieren, ob der PiP-Modus aktiviert wird (nach Android 12)

Übergebe die Statusvariable an setAutoEnterEnabled, damit deine App nur zum richtigen Zeitpunkt in den PiP-Modus wechselt:

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)

setSourceRectHint für eine flüssige Animation verwenden

Die setSourceRectHint API erstellt eine flüssigere Animation für den Wechsel in den PiP-Modus. Unter Android 12 und höher wird außerdem eine flüssigere Animation beim Beenden des Bild-im-Bild-Modus erstellt. Fügen Sie diese API dem PiP-Builder hinzu, um den Bereich der Aktivität anzugeben, der nach dem Übergang in den PiP-Modus sichtbar ist.

  1. Füge setSourceRectHint() nur dann zu builder hinzu, wenn der Status definiert, dass die App in den Bild-im-Bild-Modus wechseln soll. So wird vermieden, dass sourceRect berechnet wird, wenn die App nicht in den PiP-Modus wechseln muss.
  2. Verwenden Sie zum Festlegen des sourceRect-Werts die layoutCoordinates, die von der Funktion onGloballyPositioned für den Modifikator zurückgegeben werden.
  3. Rufen Sie setSourceRectHint() für builder auf und übergeben Sie die 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)