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

Включить дисплей от края до края
Если ваше приложение ориентировано на SDK 35 или более позднюю версию, функция отображения от края до края автоматически включается для устройств Android 15 или более поздних версий.
Чтобы включить режим «от края до края» в предыдущих версиях Android, вручную вызовите метод enableEdgeToEdge в onCreate вашего Activity .
Котлин
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.enableEdgeToEdge(window)
...
}
Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowCompat.enableEdgeToEdge(getWindow());
...
}
По умолчанию enableEdgeToEdge() делает системные панели прозрачными, за исключением режима навигации с тремя кнопками, где панель навигации получает полупрозрачную завесу. Цвета системных значков и завесы регулируются в зависимости от светлой или темной темы оформления системы.
Чтобы включить отображение от края до края в вашем приложении без использования функции enableEdgeToEdge() , см. раздел «Настройка отображения от края до края вручную» .
Обработка наложений с помощью вставок.
Некоторые элементы вашего приложения могут отображаться за системными панелями, как показано на рисунке 3.
Вы можете устранить наложения, реагируя на отступы (insets), которые определяют, какие части экрана пересекаются с системным пользовательским интерфейсом, таким как панель навигации или строка состояния. Пересечение может означать отображение поверх контента, а также информировать ваше приложение о системных жестах.
К типам отступов, применяемым при отображении приложения от края до края, относятся:
Вставки в системные панели: лучше всего подходят для элементов интерфейса, на которые можно нажимать и которые не должны быть визуально закрыты системными панелями.
Вставки для вырезов в экране: для областей, где из-за формы устройства может потребоваться вырез в экране.
Системные вставки для жестов: для областей навигации с помощью жестов, используемых системой и имеющих приоритет над вашим приложением.
Вставки системных планок
Отступы системной панели — наиболее часто используемый тип отступов. Они представляют собой область, где отображается системный пользовательский интерфейс по оси 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 }
Java
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:

Вставки с вырезами для дисплея
На некоторых устройствах есть вырезы в экране. Обычно вырез находится в верхней части экрана и расположен в строке состояния. В альбомной ориентации экрана вырез может располагаться по вертикальному краю. В зависимости от содержимого, отображаемого вашим приложением на экране, следует использовать отступы (padding), чтобы избежать вырезов в экране, поскольку по умолчанию приложения будут отображать контент в этих вырезах.
Например, на многих экранах приложений отображается список элементов. Не закрывайте элементы списка вырезом в экране или системными панелями.
Котлин
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 }
Java
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 , чтобы отступы прокручивались вместе с элементами списка. Это позволит элементам скрываться за системными полосами при прокрутке пользователем, как показано в следующем примере.
<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 }
Java
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 Components (com.google.android.material), основанные на представлениях, автоматически обрабатывают отступы, включая BottomAppBar , BottomNavigationView , NavigationRailView и NavigationView
Однако AppBarLayout не обрабатывает отступы автоматически. Добавьте android:fitsSystemWindows="true" , чтобы обработать верхние отступы.
Узнайте, как работать с отступами в компонентах Material в 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)
Java
// 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())
Java
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
Java
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
Защита системной панели
Как только ваше приложение будет ориентировано на SDK 35 или выше, будет обеспечена полная прозрачность экрана . Строка состояния системы и панели навигации жестами будут прозрачными, но панель навигации с тремя кнопками будет полупрозрачной. Вызовите enableEdgeToEdge для обеспечения обратной совместимости.
Однако настройки по умолчанию могут не подойти для всех сценариев использования. Обратитесь к рекомендациям по дизайну системной панели Android и разделу «Дизайн от края до края», чтобы определить, использовать ли прозрачную или полупрозрачную системную панель.
Создать прозрачные системные панели
Создайте прозрачную строку состояния, ориентируясь на Android 15 (SDK 35) или более поздние версии, или вызвав функцию enableEdgeToEdge() с аргументами по умолчанию для более ранних версий.
Создайте прозрачную панель навигации жестами, ориентируясь на Android 15 или выше, или вызвав метод enableEdgeToEdge() с аргументами по умолчанию для более ранних версий. Для панели навигации с тремя кнопками установите Window.setNavigationBarContrastEnforced в false , иначе будет применена полупрозрачная ширма.
Создайте полупрозрачные системные стержни
Чтобы создать полупрозрачную строку состояния, выполните следующие действия:
- Обновите зависимость
androidx-coreдо версии 1.16.0-beta01 или выше. - Оберните ваш XML-макет в
androidx.core.view.insets.ProtectionLayoutи присвойте ему идентификатор. - Для настройки защиты, указав сторону и параметр
GradientProtectionдля строки состояния, используйте программный доступProtectionLayout
<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>
findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color paneBackgroundColor ) ) )
Убедитесь, что ColorInt передаваемое в GradientProtection соответствует фону содержимого. Например, в макете «список-подробности», отображаемом на складной панели, могут быть разные GradientProtections разных цветов для панели списка и панели с подробной информацией.
Не создавайте полупрозрачную панель навигации с помощью жестов. Чтобы создать полупрозрачную панель навигации с тремя кнопками, выполните одно из следующих действий:
- Если ваш макет уже обернут в
ProtectionView, вы можете передать дополнительнуюColorProtectionилиGradientProtectionв методsetProtections. Перед этим убедитесь, чтоwindow.isNavigationBarContrastEnforced = false. - В противном случае установите
window.isNavigationBarContrastEnforced = true. Если ваше приложение вызываетenableEdgeToEdge, window.isNavigationBarContrastEnforced = trueбудет использоваться по умолчанию.
Другие советы
Дополнительные советы по работе с вставками.
Обеспечьте прокрутку контента от края до края.
Убедитесь, что последний элемент списка не перекрывается системными полосами в вашем RecyclerView или NestedScrollView , обработав отступы и установив clipToPadding в значение false .
На следующем видео показан RecyclerView с отключенным (слева) и включенным (справа) отображением от края до края:
Примеры кода можно найти в разделе «Создание динамических списков с помощью RecyclerView» .
Размещайте диалоговые окна в полноэкранном режиме от края до края.
Чтобы диалоговое окно отображалось во весь экран, вызовите enableEdgeToEdge для этого диалогового окна.
Котлин
class MyAlertDialogFragment : DialogFragment() {
override fun onStart(){
super.onStart()
dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
}
...
}
Java
public class MyAlertDialogFragment extends DialogFragment {
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
Window window = dialog.getWindow();
if (window != null) {
WindowCompat.enableEdgeToEdge(window);
}
}
}
...
}
Дополнительные ресурсы
Для получения дополнительной информации о нанесении покрытия от края до края см. следующие источники.
Блоги
- Вставки с подсказками по обработке режима "от края до края" в Android 15.
- WindowInsets — обработчики событий компоновки
Дизайн
Другая документация
Видео
