Введите PiP в правильное время

Ваше приложение не должно переходить в режим PiP в следующих ситуациях:

  • Если видео остановлено или поставлено на паузу.
  • Если вы находитесь на другой странице приложения, чем видеоплеер.

Чтобы контролировать, когда ваше приложение переходит в режим PiP, добавьте переменную, которая отслеживает состояние видеоплеера, используя mutableStateOf .

Переключение состояния в зависимости от того, воспроизводится ли видео

Чтобы переключить состояние в зависимости от того, воспроизводится ли видеопроигрыватель, добавьте прослушиватель в видеопроигрыватель. Переключите состояние вашей переменной состояния в зависимости от того, играет игрок или нет:

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

Переключение состояния в зависимости от того, выпущен ли игрок

Когда проигрыватель отпущен, установите для переменной состояния значение false :

fun releasePlayer() {
    shouldEnterPipMode = false
}

Используйте состояние, чтобы определить, включен ли режим PiP (до Android 12)

  1. Поскольку при добавлении PiP до 12 используется DisposableEffect , вам необходимо создать новую переменную с помощью rememberUpdatedState с newValue , установленным в качестве переменной состояния. Это гарантирует, что обновленная версия будет использоваться в DisposableEffect .
  2. В лямбда-выражение, определяющее поведение при срабатывании OnUserLeaveHintListener , добавьте оператор if с переменной состояния вокруг вызова 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: () -> 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")
    }

Используйте состояние, чтобы определить, включен ли режим PiP (после Android 12)

Передайте переменную состояния в setAutoEnterEnabled , чтобы ваше приложение переходило в режим PiP только в нужный момент:

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 для реализации плавной анимации.

API setSourceRectHint создает более плавную анимацию для перехода в режим PiP. В Android 12+ он также создает более плавную анимацию при выходе из режима PiP. Добавьте этот API в конструктор PiP, чтобы указать область действия, которая будет видна после перехода в PiP.

  1. Добавляйте setSourceRectHint() в builder только в том случае, если состояние определяет, что приложение должно перейти в режим PiP. Это позволяет избежать вычисления sourceRect , когда приложению не требуется вводить PiP.
  2. Чтобы установить значение sourceRect , используйте layoutCoordinates , заданные функцией onGloballyPositioned в модификаторе.
  3. Вызовите setSourceRectHint() в builder и передайте переменную 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)