Приложение не должно переходить в режим "Картинка в картинке" в следующих случаях:
- Видео остановлено или приостановлено.
- Если вы находитесь не на странице с видеопроигрывателем.
Чтобы контролировать, когда приложение переходит в режим "Картинка в картинке", добавьте переменную, которая отслеживает состояние видеопроигрывателя с помощью mutableStateOf.
Переключать состояние в зависимости от того, воспроизводится ли видео
Чтобы переключать состояние в зависимости от того, воспроизводится ли видео, добавьте прослушиватель в видеопроигрыватель. Переключайте состояние переменной в зависимости от того, играет ли пользователь:
player.addListener(object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { shouldEnterPipMode = isPlaying } })
Переключать состояние в зависимости от того, выпущен ли проигрыватель
Когда проигрыватель освобождается, задайте для переменной состояния значение false:
fun releasePlayer() { shouldEnterPipMode = false }
Используйте состояние, чтобы определить, включен ли режим "Картинка в картинке" (для версий до Android 12)
- Поскольку для добавления режима "Картинка в картинке" в версиях до Android 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)