В теге 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 11 или более ранней версии, выполните следующие действия:
- Добавьте версию, чтобы код был доступен только в версиях 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. - Позвоните на номер
setPictureInPictureParams(), используяfindActivity(). Позвоните по номеру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.