PiP zur richtigen Zeit starten

Ihre App sollte in den folgenden Fällen nicht in den PiP-Modus wechseln:

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

Wenn Sie festlegen möchten, wann Ihre App in den BiB-Modus wechselt, fügen Sie eine Variable hinzu, die den Status des Videoplayers mithilfe einer mutableStateOf erfasst.

Status je nach Wiedergabe des Videos umschalten

Wenn der Status je nach Wiedergabe des Videoplayers wechseln soll, fügen Sie dem Videoplayer einen Listener hinzu. Ändern Sie den Status der Statusvariablen je nachdem, ob der Spieler gerade spielt oder nicht:

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

Status umschalten, je nachdem, ob der Spieler freigegeben ist

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

fun releasePlayer() {
    shouldEnterPipMode = false
}

Mit „state“ definieren, ob der PiP-Modus aktiviert ist (vor Android 12)

  1. Da für das Hinzufügen von PiP vor Version 12 eine DisposableEffect verwendet wird, müssen Sie eine neue Variable mit rememberUpdatedState erstellen und newValue als Statusvariable festlegen. So wird sichergestellt, dass die aktualisierte Version in der DisposableEffect verwendet wird.
  2. Fügen Sie in dem Lambda, das das Verhalten bei der Auslösung von OnUserLeaveHintListener definiert, eine if-Anweisung mit der Statusvariablen um den Aufruf von enterPictureInPictureMode() herum 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: () -> Unit = {
                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")
    }

Mit „state“ definieren, ob der PiP-Modus aktiviert ist (ab Android 12)

Übergeben Sie die Statusvariable an setAutoEnterEnabled, damit Ihre 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 sorgt für eine flüssigere Animation beim Wechsel in den PiP-Modus. Unter Android 12 und höher wird außerdem eine flüssigere Animation beim Beenden des PiP-Modus erstellt. Fügen Sie diese API dem PiP-Builder hinzu, um den Bereich der Aktivität anzugeben, der nach dem Wechsel zu PiP sichtbar ist.

  1. Fügen Sie setSourceRectHint() nur zu builder hinzu, wenn der Status definiert, dass die App in den PiP-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 den layoutCoordinates, der von der Funktion onGloballyPositioned für den Modifikator angegeben wird.
  3. Rufe setSourceRectHint() im builder auf und übergebe 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)