Метод systemUiVisibility устарел в Android. Чем его заменить в Kotlin?
Современная замена 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().
Ответов пока нет.
Войдите чтобы оставить ответ