После того, как вы нацелитесь на SDK 35 или выше на устройстве под управлением Android 15 или выше, ваше приложение будет отображаться от края до края. Окно охватывает всю ширину и высоту дисплея, рисуясь за системными панелями. Системные панели включают строку состояния, строку заголовка и панель навигации.
У многих приложений есть верхняя панель приложений. Верхняя панель приложений должна растягиваться до верхнего края экрана и отображаться за строкой состояния. При желании верхняя панель приложений может сжиматься до высоты строки состояния при прокрутке содержимого.
Во многих приложениях также есть нижняя панель приложений или нижняя панель навигации. Эти панели также должны растягиваться до нижнего края экрана и отображаться за панелью навигации. В противном случае приложения должны показывать прокручиваемый контент за панелью навигации.
При реализации макета «от края до края» в вашем приложении помните следующее:
- Включить дисплей от края до края
- Устраните любые визуальные наложения.
- Рассмотрите возможность показа сеток за системными решетками.

Включить отображение от края до края
Если ваше приложение ориентировано на SDK 35 или более позднюю версию, Edge-to-Edge автоматически включается для устройств Android 15 или более поздней версии.
Чтобы включить функцию Edge-to-Edge на предыдущих версиях Android, выполните следующие действия:
Добавьте зависимость к библиотеке
androidx.activity
в файлеbuild.gradle
вашего приложения или модуля:Котлин
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Круто
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }Импортируйте функцию расширения
enableEdgeToEdge
в свое приложение:
Вручную включите edge-to-edge, вызвав enableEdgeToEdge
в onCreate
вашего Activity
. Его следует вызывать до setContentView
.
Котлин
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Ява
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
По умолчанию enableEdgeToEdge()
делает системные панели прозрачными, за исключением режима навигации с 3 кнопками, где строка состояния становится полупрозрачной сеткой. Цвета системных значков и сетки настраиваются на основе системной светлой или темной темы.
Функция enableEdgeToEdge()
автоматически объявляет, что приложение должно быть размещено от края до края, и настраивает цвета системных панелей.
Чтобы включить отображение от края до края в вашем приложении без использования функции enableEdgeToEdge()
, см . раздел Ручная настройка отображения от края до края .
Обработка перекрытий с помощью вставок
Некоторые из представлений вашего приложения могут отображаться за системными панелями, как показано на рисунке 3.
Вы можете устранить перекрытия, реагируя на вставки, которые указывают, какие части экрана пересекаются с системным пользовательским интерфейсом, таким как панель навигации или строка состояния. Пересечение может означать отображение над содержимым, но оно также может информировать ваше приложение о системных жестах.
Типы вставок, которые применяются для отображения вашего приложения от края до края:
Вставки системных панелей: лучше всего подходят для видов, на которые можно нажимать и которые не должны визуально закрываться системными панелями.
Вырезы на дисплее: для областей, где из-за формы устройства может быть вырез на экране.
Вставки системных жестов: для областей навигации с помощью жестов, используемых системой, которые имеют приоритет над вашим приложением.
Вставки системных панелей
Вставки системной панели являются наиболее часто используемым типом вставок. Они представляют собой область, в которой системный пользовательский интерфейс отображается на оси Z над вашим приложением. Их лучше всего использовать для перемещения или заполнения представлений в вашем приложении, которые можно нажимать и которые не должны визуально закрываться системными панелями.
Например, плавающая кнопка действия (FAB) на рисунке 3 частично закрыта панелью навигации:

Чтобы избежать такого визуального наложения в режиме жестов или кнопок, можно увеличить поля представления с помощью getInsets(int)
с WindowInsetsCompat.Type.systemBars()
.
В следующем примере кода показано, как реализовать вставки системной панели:
Котлин
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Ява
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
Если применить это решение к примеру, показанному на рисунке 3, то в режиме кнопок визуального перекрытия не возникнет, как показано на рисунке 4:

То же самое относится и к режиму навигации с помощью жестов, как показано на рисунке 5:

Вставки для вырезов на дисплее
На некоторых устройствах есть вырезы на дисплее. Обычно вырез находится в верхней части экрана и включен в строку состояния. Когда экран устройства находится в ландшафтном режиме, вырез может быть на вертикальном краю. В зависимости от содержимого, которое ваше приложение отображает на экране, вам следует реализовать отступы, чтобы избежать вырезов на дисплее, так как по умолчанию приложения будут рисовать в вырезе на дисплее.
Например, многие экраны приложений показывают список элементов. Не закрывайте элементы списка вырезом на дисплее или системными панелями.
Котлин
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Ява
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
Определите значение WindowInsetsCompat
, взяв логическое ИЛИ системных панелей и типов вырезов дисплея.
Установите clipToPadding
для RecyclerView
, чтобы padding прокручивался вместе с элементами списка. Это позволяет элементам заходить за системные панели, когда пользователь прокручивает, как показано в следующем примере.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
Системные вставки жестов
Вставки системных жестов представляют области окна, где системные жесты имеют приоритет над вашим приложением. Эти области показаны оранжевым цветом на рисунке 6:

Как и в случае с вставками системной панели, вы можете избежать перекрытия вставок системных жестов, используя getInsets(int)
с WindowInsetsCompat.Type.systemGestures()
.
Используйте эти вставки для перемещения или отступа прокручиваемых представлений от краев. Обычные варианты использования включают нижние листы , пролистывание в играх и карусели, реализованные с помощью ViewPager2
.
В Android 10 и более поздних версиях системные вставки жестов содержат нижнюю вставку для жеста «Домой», а также левую и правую вставки для жестов «Назад»:

В следующем примере кода показано, как реализовать вставки системных жестов:
Котлин
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Ява
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Материальные компоненты
Многие компоненты Android Material на основе представлений (com.google.android.material) автоматически обрабатывают вставки, включая BottomAppBar
, BottomNavigationView
, NavigationRailView
и NavigationView
Однако AppBarLayout
не обрабатывает вставки автоматически. Добавьте android:fitsSystemWindows="true"
для обработки верхних вставок.
Узнайте, как обрабатывать вставки с компонентами материалов в Compose .
Обратная совместимость вставной диспетчеризации
Чтобы остановить отправку вставок в дочерние представления и избежать избыточного заполнения, вы можете использовать вставки с помощью константы WindowInsetsCompat.CONSUMED
. Однако на устройствах под управлением Android 10 (уровень API 29 и более ранние) вставки не отправляются в родственные элементы после вызова WindowInsetsCompat.CONSUMED
, что может привести к непреднамеренному визуальному наложению.

Чтобы убедиться, что вставки отправляются на родственные устройства для всех поддерживаемых версий Android, используйте ViewGroupCompat#installCompatInsetsDispatch
перед использованием вставок, доступных в AndroidX Core и Core-ktx 1.16.0-alpha01 и выше.
Котлин
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView)
Ява
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);

Режим погружения
Некоторый контент лучше всего воспринимается в полноэкранном режиме, что дает пользователю более захватывающий опыт. Вы можете скрыть системные панели для иммерсивного режима с помощью библиотек WindowInsetsController
и WindowInsetsControllerCompat
:
Котлин
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Ява
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
Дополнительную информацию о реализации этой функции см. в разделе Скрытие системных панелей для режима погружения .
Значки системной панели
Вызов enableEdgeToEdge
обеспечивает обновление цветов значков системной панели при изменении темы устройства.
При переходе от края к краю вам может потребоваться вручную обновить цвета значков системной панели, чтобы они контрастировали с фоном вашего приложения. Например, чтобы создать светлые значки строки состояния:
Котлин
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
Ява
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
Защита системной панели
Как только ваше приложение станет ориентировано на SDK 35 или выше, будет применен edge-to-edge . Строка состояния системы и панели навигации жестов прозрачны, но панель навигации с тремя кнопками полупрозрачна. Вызовите enableEdgeToEdge
, чтобы сделать это обратно совместимым.
Однако системные настройки по умолчанию могут не работать во всех случаях использования. Ознакомьтесь с руководством по дизайну системных панелей Android и дизайном Edge-to-edge, чтобы определить, следует ли использовать прозрачные или полупрозрачные системные панели.
Создать прозрачные системные панели
Создайте прозрачную строку состояния, указав версию Android 15 (SDK 35) или выше или вызвав enableEdgeToEdge()
с аргументами по умолчанию для более ранних версий.
Создайте прозрачную панель навигации жестов, нацелившись на Android 15 или выше или вызвав enableEdgeToEdge()
с аргументами по умолчанию для более ранних версий. Для трехкнопочной панели навигации установите Window.setNavigationBarContrastEnforced
на false
, иначе будет применена полупрозрачная сетка.
Создание полупрозрачных системных панелей
Чтобы создать полупрозрачную строку состояния, выполните следующие действия:
- Обновите зависимость
androidx-core
до версии 1.16.0-beta01 или выше. - Оберните свой XML-макет в
androidx.core.view.insets.ProtectionLayout
и назначьте идентификатор. - Программно обращайтесь к
ProtectionLayout
, чтобы установить защиту, указав сторону иGradientProtection
для строки состояния.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
val red = 52 val green = 168 val blue = 83 findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color // alpha = 204 for an 80% gradient Color.argb(204, red, green, blue) ) ) )
Убедитесь, что ColorInt
, переданный в GradientProtection
соответствует фону контента. Например, макет списка-детали, отображаемый на складном устройстве, может иметь разные GradientProtections
разных цветов для панели списка и панели деталей.
Не создавайте полупрозрачную панель навигации жестов. Чтобы создать полупрозрачную панель навигации с тремя кнопками, выполните одно из следующих действий:
- Если ваш макет уже обернут в
ProtectionView
, вы можете передать дополнительныйColorProtection
илиGradientProtection
в методsetProtections
. Перед этим убедитесь, чтоwindow.isNavigationBarContrastEnforced = false
. - В противном случае установите
window.isNavigationBarContrastEnforced = true
. Если ваше приложение вызываетenableEdgeToEdge, window.isNavigationBarContrastEnforced = true
является значением по умолчанию.
Другие советы
Убедитесь, что последний элемент списка не закрыт системными панелями в RecyclerView
или NestedScrollView
, обработав вставки и установив clipToPadding
в false
.
На следующем видео показан RecyclerView
с отключенным (слева) и включенным (справа) дисплеем от края до края:
Пример кода см. в разделе Создание динамических списков с помощью RecyclerView .
Дополнительные ресурсы
Дополнительную информацию о переходе от края к краю можно найти в следующих ссылках.
Блоги
- Советы по обработке вставок для обеспечения безопасности Android 15 от края до края
- WindowInsets — прослушиватели макетов
Дизайн
Другая документация
Видео