Вырез на экране – это область на некоторых устройствах, которая заходит на поверхность экрана. Это позволяет использовать экран от края до края, оставляя место для важных датчиков на передней панели устройства.
Вырезы на экране поддерживаются на устройствах с Android 9 (уровень API 28) и более поздними версиями ОС. Однако производители устройств могут поддерживать вырезы на экране и на устройствах с Android 8.1 или более ранней версией.
В этом документе описывается, как реализовать поддержку устройств с вырезами, в том числе как работать с областью выреза – прямоугольником на поверхности дисплея, содержащим вырез.
Выберите, как приложение должно обрабатывать области выреза
Чтобы контент не перекрывался вырезом, обычно достаточно убедиться, что он не перекрывается строкой состояния и панелью навигации. Если вы выполняете рендеринг в области выреза, используйте WindowInsetsCompat.getDisplayCutout(), чтобы получить объект DisplayCutout, который содержит безопасные отступы и ограничивающую рамку для каждого выреза. Эти API позволяют проверить, перекрывает ли вырез ваш контент, чтобы вы могли изменить его положение, если это необходимо.
Вы также можете определить, будет ли контент размещаться за областью выреза. Атрибут макета окна layoutInDisplayCutoutMode определяет, как контент отображается в области выреза.
Для layoutInDisplayCutoutMode можно задать одно из следующих значений:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT– контент отображается в области выреза, если вырез на экране находится в системной строке. В противном случае окно не будет перекрывать вырез на экране. Например, при горизонтальной ориентации контент может отображаться с черными полосами по краям. Если приложение использует SDK 35, то для неплавающих окон это интерпретируется какALWAYS.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS: контент всегда может заходить на область выреза. Если ваше приложение поддерживает SDK 35 и работает на устройстве с Android 15, это единственный разрешенный режим для неплавающих окон, обеспечивающий отображение от края до края.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES– контент отображается в области выреза как в вертикальном, так и в горизонтальном режиме. Не используйте для плавающих окон. Если приложение использует SDK 35, то для неплавающих окон это интерпретируется какALWAYS.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER– контент никогда не отображается в области выреза. Если приложение использует SDK 35, для неплавающих окон это интерпретируется какALWAYS.
Режим выреза можно задать программно или с помощью стиля в объекте activity. В примере ниже определяется стиль, который применяет к действию атрибут LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
Ниже приведены подробные сведения о режимах выреза.
Настройки по умолчанию
Если приложение использует SDK 35 и работает на устройстве с Android 15, то LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS – это режим работы по умолчанию, а LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT интерпретируется как LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS для неплавающих окон.
В противном случае по умолчанию используется LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT.
Отрисовка контента в областях вырезов по короткому краю
Если приложение использует SDK 35 и работает на устройстве с Android 15, то для неплавающих окон LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES интерпретируется как LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS.
При использовании LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES контент расширяется в область выреза на коротком краю экрана как в портретной, так и в альбомной ориентации, независимо от того, скрыты или видны системные строки. При использовании этого режима убедитесь, что важный контент не перекрывается вырезом.
На изображении ниже показан пример LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES для устройства в вертикальной ориентации.
На изображении ниже показан пример LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES для устройства в горизонтальной ориентации.
В этом режиме окно расширяется под вырезы на коротком краю дисплея как в портретной, так и в альбомной ориентации, независимо от того, скрывает ли окно системные строки.
Вырез в углу считается расположенным на коротком краю:
Никогда не показывать контент в области выреза на экране
Если приложение использует SDK 35 и работает на устройстве с Android 15, то для неплавающих окон LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER интерпретируется как LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS.
Если задано значение LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER, окно никогда не перекрывает вырез.
Ниже приведен пример LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER в вертикальной ориентации.
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER для вертикальной ориентации.
Ниже приведен пример LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER в горизонтальном режиме:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER в горизонтальном режиме.
Рекомендации по поддержке вырезов на экране
При работе с вырезами на экране учитывайте следующее:
- Учитывайте расположение важных элементов интерфейса. Не допускайте, чтобы вырез закрывал важный текст, элементы управления или другую информацию.
- Не размещайте и не расширяйте интерактивные элементы, требующие точного распознавания касаний, в области выреза. Чувствительность экрана в области выреза может быть ниже.
По возможности используйте
WindowInsetsCompat, чтобы получить высоту строки состояния и определить подходящие поля для контента. Не задавайте высоту строки состояния в коде, иначе контент может перекрываться или обрезаться.
Рисунок 7. Используйте WindowInsetsCompat, чтобы контент не перекрывался и не обрезался.С помощью
View.getLocationInWindow()определите, сколько места на экране занимает ваше приложение. Не предполагайте, что приложение использует все окно, и не используйтеView.getLocationOnScreen().Если в приложении используется режим погружения, выберите
always,shortEdgesилиnever. При стандартном поведении контент приложения может отображаться в области выреза, когда системные строки видны, но не в режиме погружения. В результате контент перемещается вверх и вниз во время переходов, как показано в примере ниже.
Рисунок 8. Пример перемещения контента вверх и вниз во время переходов. В режиме погружения будьте осторожны с координатами окна и экрана, поскольку приложение не использует весь экран, когда оно ограничено черными полосами. Из-за кашетирования координаты от начала экрана не совпадают с координатами от начала окна. При необходимости вы можете преобразовать координаты экрана в координаты представления с помощью
getLocationOnScreen(). На изображении ниже показано, как меняются координаты при кашетировании.
Рисунок 9. Координаты окна и экрана при кашетировании контента. При обработке
MotionEventиспользуйтеMotionEvent.getX()иMotionEvent.getY(), чтобы избежать подобных проблем с координатами. Не используйтеMotionEvent.getRawX()илиMotionEvent.getRawY().
Проверьте, как отображается ваш контент
Протестируйте все экраны и функции приложения. По возможности протестируйте приложение на устройствах с разными типами вырезов. Если у вас нет устройства с вырезом, вы можете смоделировать распространенные конфигурации вырезов на любом устройстве или эмуляторе с Android 9 или более поздней версии. Для этого выполните следующие действия:
- Включите режим разработчика.
- В разделе Для разработчиков прокрутите экран вниз до раздела Отрисовка и выберите Имитировать экран с вырезом.
Выберите тип выреза.
Рисунок 10. Для разработчиков: инструменты для проверки отображения контента.
Дополнительные ресурсы
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT