Avatar ·

Метод systemUiVisibility устарел в Android. Чем его заменить в Kotlin?

Всем привет! Я пишу простое приложение на Kotlin, и мне нужно сделать полноэкранный режим, чтобы скрыть системную панель навигации и строку состояния. Раньше я использовал такой код: ```kotlin window.decorView.systemUiVisibility = ( View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY ) ``` Но студия подчёркивает `systemUiVisibility` как устаревшее свойство (deprecated). В документации написано, что начиная с Android 11 (API 30) его не рекомендуется использовать, а в будущих версиях могут полностью удалить. Я использую compileSdk 34 и minSdk 26. Пробовал гуглить, но нашёл много разрозненной информации: кто-то советует `WindowInsetsController`, кто-то — `WindowCompat.setDecorFitsSystemWindows()`, а кто-то вообще говорит про `enableEdgeToEdge()`. Я новичок, запутался окончательно. Подскажите, пожалуйста, какой самый правильный и современный способ скрыть системные панели в Android на Kotlin в 2024 году? Желательно с рабочим примером кода. Заранее спасибо! <<>>

Современная замена systemUiVisibility: WindowInsetsController

Начиная с Android 11 (API 30) метод View.systemUiVisibility официально признан устаревшим. Вместо него Google рекомендует использовать WindowInsetsController — API для управления системными окнами (строка состояния, панель навигации, клавиатура и т.д.).

Вот как правильно переписать ваш код для создания полноэкранного режима с возможностью выхода из него по свайпу (immersive sticky):


// В Activity, например в onCreate() или после setContentView()
window.setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
)

val controller = window.insetsController

if (controller != null) {
    // Скрываем системные панели
    controller.hide(WindowInsets.Type.systemBars())

    // Делаем поведение "immersive sticky" — панели скрываются,
    // но при свайпе от края экрана временно показываются
    controller.systemBarsBehavior =
        WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

Важные моменты:

  • Проверка на null — window.insetsController может быть null на Android 10 и ниже. Для обратной совместимости используйте проверку.
  • window.setFlags(FLAG_LAYOUT_NO_LIMITS) — позволяет контенту отрисовываться под системными панелями (без этого они могут оставаться пустыми).
  • WindowInsets.Type.systemBars() — скрывает и строку состояния, и панель навигации. Можно скрывать по отдельности: WindowInsets.Type.statusBars() или WindowInsets.Type.navigationBars().

Как вернуть панели обратно?

Если нужно показать системные панели программно (например, при выходе из полноэкранного режима):


window.insetsController?.show(WindowInsets.Type.systemBars())

Альтернативный подход: enableEdgeToEdge()

Начиная с Android 15 (API 35) появился метод enableEdgeToEdge(), который автоматически настраивает отрисовку контента под системными панелями. Однако для скрытия панелей его недостаточно — нужно комбинировать с WindowInsetsController:


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    enableEdgeToEdge() // только для API 35+
    window.insetsController?.hide(WindowInsets.Type.systemBars())
}

Обратная совместимость (API 21-29)

Для старых устройств всё ещё можно использовать старый способ с проверкой версии:


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    window.insetsController?.hide(WindowInsets.Type.systemBars())
    window.insetsController?.systemBarsBehavior =
        WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
} else {
    // Старый способ для API < 30
    window.decorView.systemUiVisibility = (
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
        View.SYSTEM_UI_FLAG_FULLSCREEN or
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    )
}

Этот код безопасно работает на всех версиях Android, начиная с API 21 (Android 5.0).

<<>>

Упрощённый вариант через WindowCompat

Если вам нужно просто убрать "вырезы" (notch) и разрешить контенту занимать всю область экрана, но не скрывать панели навигации полностью — используйте WindowCompat.setDecorFitsSystemWindows():


// В Activity
WindowCompat.setDecorFitsSystemWindows(window, false)

Этот метод сам решает, как правильно настроить отступы для разных версий Android. Он не скрывает панели, но позволяет контенту рисоваться под ними — эффект "краёв к краю" (edge-to-edge).

Когда это полезно?

  • В современных Material Design приложениях, где панель инструментов (Toolbar) должна быть под строкой состояния.
  • В играх или плеерах, где нужно скрыть панели — комбинируйте с WindowInsetsController.

Обратите внимание: setDecorFitsSystemWindows(false) не отключает системные жесты, а только убирает стандартные отступы. Для полноэкранного режима всё равно нужен hide().