Ваше приложение не должно переходить в режим «картинка в картинке» в следующих ситуациях:
- Если видео остановлено или поставлено на паузу.
- Если вы находитесь на другой странице приложения, нежели видеоплеер.
Чтобы контролировать переход вашего приложения в режим «картинка в картинке», добавьте переменную, отслеживающую состояние видеоплеера, используя свойство ` mutableStateOf .
Переключение состояния в зависимости от того, воспроизводится видео.
Чтобы переключать состояние в зависимости от того, воспроизводится видеоплеер, добавьте слушатель к видеоплееру. Переключайте состояние вашей переменной состояния в зависимости от того, воспроизводится плеер или нет:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Переключение состояния в зависимости от того, отпустили ли игрока.
Когда игрок отпускается, установите переменную состояния в false :
fun releasePlayer() { shouldEnterPipMode = false }
Используйте состояние для определения того, включен ли режим «картинка в картинке» (до Android 12).
- Поскольку добавление PiP до версии 12 использует
DisposableEffect, вам необходимо создать новую переменную с помощьюrememberUpdatedState, установивnewValueв качестве переменной состояния. Это гарантирует, что вDisposableEffectбудет использоваться обновленная версия. В лямбда-функции, определяющей поведение при срабатывании
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 = 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") }
Используйте состояние для определения того, включен ли режим «картинка в картинке» (после Android 12).
Передайте вашу переменную состояния в setAutoEnterEnabled , чтобы ваше приложение переходило в режим «картинка в картинке» только в нужный момент:
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 создает более плавную анимацию при переходе в режим «картинка в картинке». В Android 12 и более поздних версиях он также создает более плавную анимацию при выходе из режима «картинка в картинке». Добавьте этот API в конструктор PiP, чтобы указать область активности, которая становится видимой после перехода в режим «картинка в картинке».
- Добавляйте
setSourceRectHint()вbuilderтолько в том случае, если состояние определяет, что приложение должно перейти в режим «картинка в картинке». Это позволит избежать вычисленияsourceRectкогда приложению не нужно переходить в режим «картинка в картинке». - Для установки значения
sourceRectиспользуйтеlayoutCoordinates, полученные из функцииonGloballyPositionedмодификатора. - Вызовите
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)