В теге activity вашего файла AndroidManifest.xml выполните следующие действия:
- Добавьте
supportsPictureInPictureи задайте для него значениеtrueчтобы объявить, что вы будете использовать в своем приложении функцию «картинка в картинке» (PiP). - Добавьте
configChangesи задайте ему значениеorientation|screenLayout|screenSize|smallestScreenSize, чтобы указать, что ваша операция обрабатывает изменения конфигурации макета. Таким образом, ваша операция не будет перезапускаться при изменении макета во время переходов в режиме «картинка в картинке».
<activity
android:name=".SnippetsActivity"
android:exported="true"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
android:theme="@style/Theme.Snippets">
В коде Compose выполните следующие действия:
- Добавьте это расширение в
Context. Оно понадобится вам несколько раз на протяжении всего руководства для доступа к заданию.internal fun Context.findActivity(): ComponentActivity { var context = this while (context is ContextWrapper) { if (context is ComponentActivity) return context context = context.baseContext } throw IllegalStateException("Picture in picture should be called in the context of an Activity") }
Добавьте приложение «Картинка в картинке при выходе» для устройств на базе Android до 12
Чтобы добавить режим «Картинка в картинке» для устройств на базе Android до 12, используйте addOnUserLeaveHintProvider . Чтобы добавить режим «Картинка в картинке» для устройств на базе Android до 12, выполните следующие действия:
- Добавьте шлюз версий, чтобы этот код был доступен только в версиях O до R.
- Используйте
DisposableEffectсContextв качестве ключа. - Внутри
DisposableEffectопределите поведение при срабатыванииonUserLeaveHintProviderс помощью лямбда-выражения. В лямбда-выражении вызовитеenterPictureInPictureMode()дляfindActivity()и передайтеPictureInPictureParams.Builder().build(). - Добавьте
addOnUserLeaveHintListenerс помощьюfindActivity()и передайте лямбда-выражение. - В
onDisposeдобавьтеremoveOnUserLeaveHintListenerс помощьюfindActivity()и передайте лямбда-выражение.
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 { 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
После Android 12 PictureInPictureParams.Builder добавляется через модификатор, который передается в видеоплеер приложения.
- Создайте
modifierи вызовите для негоonGloballyPositioned. Координаты макета будут использованы на следующем этапе. - Создайте переменную для
PictureInPictureParams.Builder(). - Добавьте оператор
ifдля проверки версии SDK (S или более поздней). Если да, добавьтеsetAutoEnterEnabledв конструктор и установите его вtrueчтобы активировать режим «картинка в картинке» при смахивании. Это обеспечивает более плавную анимацию, чем при использованииenterPictureInPictureMode. - Используйте
findActivity()для вызоваsetPictureInPictureParams(). Вызовитеbuild()вbuilderи передайте его.
val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(true) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Используйте setAspectRatio для установки соотношения сторон окна PiP.
Чтобы задать соотношение сторон окна «картинка в картинке», вы можете либо выбрать конкретное соотношение сторон, либо использовать ширину и высоту видео плеера. Если вы используете проигрыватель Media3, убедитесь, что плеер не имеет значение NULL и что размер видео плеера не равен VideoSize.UNKNOWN , прежде чем настраивать соотношение сторон.
val context = LocalContext.current val pipModifier = modifier.onGloballyPositioned { layoutCoordinates -> val builder = PictureInPictureParams.Builder() if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) { val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect() builder.setSourceRectHint(sourceRect) builder.setAspectRatio( Rational(player.videoSize.width, player.videoSize.height) ) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { builder.setAutoEnterEnabled(shouldEnterPipMode) } context.findActivity().setPictureInPictureParams(builder.build()) } VideoPlayer(pipModifier)
Если вы используете собственный плеер, задайте соотношение сторон для его высоты и ширины, используя синтаксис, специфичный для вашего плеера. Имейте в виду, что если размер плеера изменится во время инициализации и выйдет за допустимые границы соотношения сторон, приложение завершится сбоем. Возможно, вам потребуется добавить проверки, когда соотношение сторон может быть рассчитано, аналогично тому, как это реализовано в плеере Media3.