В последние годы смартфоны становятся всё ближе по функциональности к компьютерам, и многим уже заменяют ПК как основной инструмент работы. Преимуществом персональных компьютеров была многооконность, остававшаяся недоступной на смартфонах. Но с выходом Android 7.0 ситуация начала меняться и появилась поддержка многооконности.
Удобство небольшого плавающего окна с видео собеседника при свёрнутом звонке сложно переоценить -- можно продолжать диалог и параллельно вести записи или уточнять какую-то информацию. В Android есть два варианта реализации такой функциональности: поддержка работы приложения в плавающем окне и режим "picture-in-picture". В идеале приложение должно поддерживать оба подхода, но плавающее окно сложнее в разработке и накладывает определённые ограничения на дизайн приложения в целом, поэтому рассмотрим именно picture-in-picture (далее — PIP), как относительно простой способ привнести поддержку многооконности в своё приложение.
Переход в режим PIP
Режим PIP поддерживается на большинстве устройств с Android 8 и выше. Соответственно, если вы поддерживаете версии системы ниже этой, то все относящиеся к режиму PIP вызовы должны быть обернуты в проверку версии системы:
В PIP переводится всё `Activity` целиком, и для начала необходимо объявить поддержку PIP и что `Activity` обрабатывает изменения конфигурации в `AndroidManifest.xml`:
Перед использованием picture-in-picture необходимо удостовериться, что устройство пользователя поддерживает этот режим, для этого обратимся к `PackageManager`
После этого в простейшем виде переход в режим picture-in-picture делается буквально одной строкой:
Но чтобы в него перейти, надо знать, когда это удобно пользователю. Можно сделать отдельную кнопку и переходить по нажатию на неё. Наиболее распространённый подход -- автоматический переход, когда пользователь сворачивает приложение во время звонка — например, при нажатии кнопки Home или Recent.
Начиная с Android 12 это можно реализовать при помощи установки PictureInPictureParams с флагом setAutoEnterEnabled в Activity:
На устройствах с Android 11 или ниже Activit` должна явно вызывать enterPictureInPictureMode() в Activity.onUserLeaveHint:
Адаптация интерфейса
Отлично, теперь наш экран звонка автоматически переходит в режим PIP! Но там часто есть кнопки "закончить звонок" или "сменить камеру", а они не будут работать в этом режиме. Их лучше скрыть при переходе.
Для отслеживания перехода в / из режима PIP в `Activity` и `Fragment` есть метод `onPictureInPictureModeChanged`. Переопределим его и скроем лишние элементы интерфейса:
Окно PIP совсем небольшое, поэтому имеет смысл скрыть всё, кроме видео собеседника, включая видео локального пользователя -- оно всё равно будет слишком маленьким, чтобы там можно было что-либо разглядеть.
Кастомизация
Окно PIP можно дополнительно кастомизировать, передав `PictureInPictureParams` в вызов `enterPictureInPictureMode`. Возможностей кастомизации не так много, но особого внимания заслуживает возможность добавить кнопки в нижнюю часть окна. Это удобная возможность оставить экран интерактивным несмотря на то, что обычные кнопки перестают работать в режиме PIP.
Максимальное количество кнопок, которые можно добавить, зависит от многих факторов, но всегда можно добавить как минимум три. Все кнопки сверх лимита просто не будут показаны, поэтому особенно важные лучше расположить в самом начале. Узнать точный лимит в текущей конфигурации можно через метод `Activity`:
Давайте добавим в наше окно PIP кнопку окончания звонка. Для начала, как и с уведомлениями, нам понадобится `PendingIntent`, который будет отвечать за сообщение нашему приложению, что кнопка была нажата. Если вы впервые слышите про `PendingIntent`.
После этого мы можем приступить к созданию собственно описания кнопки, а именно -- `RemoteAction`
Наше "действие" готово, теперь необходимо добавить его к параметрам PIP и, впоследствии, к вызову перехода в режим
Для начала создадим Builder наших параметров кастомизации:
Начиная с Android 8 можно определить область экрана, которая будет отображаться при переходе в PIP. Это можно сделать используя метод setSourceRectHint:
Помимо кнопок, через параметры можно задать соотношение сторон окна PIP или параметры анимации перехода в этот режим.
Итог
Мы рассмотрели достаточно простой, но очень удобный вариант использования возможностей многооконности системы для улучшения пользовательского опыта, научились добавлять к окну PIP кнопки и адаптировать наш интерфейс при переходе в этот режим и из него.
Комментарии