Запрет поворота экрана в Android Studio чаще всего сводится к одной строке — атрибуту android:screenOrientation="portrait" в файле AndroidManifest.xml, и без неё активность при наклоне устройства пересоздаётся, теряя введённые данные и состояние экрана. Это стандартное поведение Android: при смене ориентации система уничтожает Activity и создаёт её заново, что для многих приложений неприемлемо.
В этой статье разберём все рабочие способы зафиксировать ориентацию: через манифест, программно из кода, для отдельных экранов и всего приложения сразу. Также рассмотрим, как сохранить данные, если блокировать поворот нельзя, и какие подводные камни встречаются при тестировании на эмуляторе.
Зачем блокировать ориентацию экрана
Не каждое приложение корректно выглядит в горизонтальном режиме. Игры, сканеры документов, экраны с камерой и сложные формы ввода часто проектируются строго под портретную ориентацию, и произвольный поворот ломает вёрстку или прерывает пользовательский сценарий.
Вторая причина — пересоздание Activity. При повороте система вызывает onDestroy() и заново создаёт экран, поэтому несохранённый текст в полях, позиция списка и результаты асинхронных операций могут пропасть. Проще запретить поворот, чем продумывать сохранение всего состояния, если дизайн этого не требует.
- 📱 Стабильная вёрстка без адаптации под landscape-режим
- 💾 Отсутствие потери данных из-за пересоздания Activity
- 🎮 Корректная работа игр и приложений с камерой
- ⚡ Меньше кода для обработки смены конфигурации
Способ 1: атрибут screenOrientation в манифесте
Самый простой и надёжный метод — прописать ориентацию декларативно. Откройте файл app/src/main/AndroidManifest.xml и добавьте атрибут android:screenOrientation в нужную активность:
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:exported="true">
Для горизонтальной фиксации используйте значение landscape. Если нужно, чтобы ориентация следовала за датчиком, но не переворачивалась «вверх ногами», подойдут значения sensorPortrait и sensorLandscape — они разрешают переворот на 180 градусов, но не переключают режим.
⚠️ Внимание: значениеportraitжёстко фиксирует одно положение. На некоторых устройствах, где портрет «вверх ногами» удобен (например, при подключённом кабеле снизу), это может быть неудобно. В таких случаях лучше использоватьsensorPortrait.
Чтобы применить настройку ко всему приложению сразу, атрибут можно указать в теге <application> — тогда он унаследуется всеми активностями, у которых не задано собственное значение.
Способ 2: программная блокировка в коде
Иногда ориентацию нужно менять динамически — например, разрешить поворот только на экране просмотра видео. Для этого служит метод setRequestedOrientation(), который вызывается из Activity.
На Kotlin код выглядит так:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
setContentView(R.layout.activity_main)
}
На Java аналогично:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
}
Не забудьте импортировать класс android.content.pm.ActivityInfo. Чтобы вернуть системное поведение, передайте значение SCREEN_ORIENTATION_UNSPECIFIED — тогда ориентация снова будет управляться настройками устройства и датчиком поворота.
Сравнение значений screenOrientation
Атрибут принимает больше десятка значений, но на практике чаще всего нужны лишь несколько. Таблица ниже поможет выбрать подходящее.
| Значение | Поведение | Когда использовать |
|---|---|---|
portrait | Строго вертикально, без переворота | Обычные приложения, формы, ленты |
sensorPortrait | Вертикально, переворот на 180° разрешён | Устройства с зарядкой снизу, планшеты |
landscape | Строго горизонтально | Игры, видеоплееры |
sensorLandscape | Горизонтально с переворотом на 180° | Видео, чтобы кабель был с удобной стороны |
unspecified | Системное поведение по умолчанию | Когда блокировка не нужна |
Отметим, что часть значений (например, reversePortrait) появилась в более поздних версиях Android, поэтому на старых устройствах поведение может отличаться — проверяйте на реальных девайсах с минимальной целевой версией вашего приложения.
Проверка результата на эмуляторе и устройстве
После добавления атрибута запустите приложение и попробуйте повернуть экран. На эмуляторе поворот выполняется кнопками Rotate left / Rotate right на панели управления эмулятором или сочетаниями клавиш, которые можно посмотреть в настройках эмулятора — они зависят от версии Android Studio.
☑️ Проверка блокировки поворота
Если экран продолжает поворачиваться, в первую очередь убедитесь, что вы редактировали манифест основного модуля, а не, например, манифест библиотеки или build-варианта. Также проверьте, не переопределяет ли код в onCreate() ориентацию через setRequestedOrientation() — программный вызов имеет приоритет над манифестом.
⚠️ Внимание: изменения в AndroidManifest.xml применяются при новой установке или пересборке приложения. Если вы тестируете через мгновенный запуск (Apply Changes), перезапустите приложение полностью — иначе старая конфигурация может остаться в силе.
Альтернатива: сохранение состояния вместо блокировки
Блокировать поворот — не единственный выход. Современный подход в Android-разработке — не запрещать поворот, а корректно переживать пересоздание Activity с помощью компонентов архитектуры. Это особенно важно для планшетов и складных устройств, где горизонтальный режим — норма.
Основные инструменты для этого:
- 🧩 ViewModel — переживает пересоздание Activity и хранит данные экрана
- 💾 SavedStateHandle / onSaveInstanceState() — сохранение состояния при уничтожении процесса
- 🗄️ Room или DataStore — для данных, которые должны переживать закрытие приложения
- 📐 Отдельные layout-файлы в папке
res/layout-land— для адаптации вёрстки под горизонтальный режим
Также существует атрибут android:configChanges="orientation|screenSize", который запрещает пересоздание Activity при повороте, передавая обработку в метод onConfigurationChanged(). Однако Google официально не рекомендует использовать его как замену нормальному сохранению состояния — это считается обходным путём и не защищает от пересоздания по другим причинам (смена языка, темы, нехватка памяти).
Почему configChanges считается плохой практикой
Атрибут android:configChanges отключает пересоздание только для перечисленных изменений конфигурации. Приложение всё равно будет пересоздано при смене локали, темы, шрифтов, а также при уничтожении процесса системой в фоне. Кроме того, при использовании configChanges ресурсы (layout-land, квалификаторы размеров) не перезагружаются автоматически — их нужно применять вручную, что усложняет код и провоцирует ошибки.
Типичные ошибки при блокировке поворота
Разберём ситуации, когда запрет вроде бы установлен, но экран всё равно поворачивается или приложение ведёт себя странно.
Первая частая причина — программный вызов в коде, который переопределяет манифест. Поищите по проекту строку setRequestedOrientation или requestedOrientation: возможно, блокировка снимается в базовой Activity или сторонней библиотеке (например, плееры часто сами управляют ориентацией).
Вторая ситуация — поворот работает на эмуляторе, но не на устройстве, или наоборот. Возможная причина — отключённый автоповорот в системных настройках устройства: тогда кажется, что блокировка работает, хотя поворачиваться экрану просто не даёт система. Проверяйте с включённым автоповоротом.
Третий момент касается Activity с диалоговой темой и прозрачных активностей: на некоторых версиях Android фиксация ориентации для таких экранов вызывала сбои. Если приложение падает при запуске прозрачной Activity с screenOrientation, попробуйте убрать атрибут или сменить тему — это известная особенность ряда версий платформы.
Часто задаваемые вопросы
Как запретить поворот экрана для всего приложения сразу?
Добавьте атрибут android:screenOrientation="portrait" в тег <application> файла AndroidManifest.xml. Все активности без собственного значения унаследуют эту настройку. Для отдельных экранов можно задать другое значение, например разрешить landscape в видеоплеере.
Что важнее: манифест или setRequestedOrientation в коде?
Программный вызов setRequestedOrientation() имеет приоритет над атрибутом в манифесте. Если в коде где-то меняется ориентация, значение из AndroidManifest.xml для этого экрана перестаёт действовать.
Чем portrait отличается от sensorPortrait?
Значение portrait фиксирует строго одно вертикальное положение. sensorPortrait разрешает переворот на 180 градусов (портрет «вверх ногами»), но не переключается в горизонтальный режим. Для планшетов и устройств с нижним разъёмом второй вариант удобнее.
Можно ли запретить поворот только на время, например во время загрузки?
Да. Вызовите setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED) в начале операции — это зафиксирует текущую ориентацию. По завершении передайте SCREEN_ORIENTATION_UNSPECIFIED, чтобы вернуть обычное поведение.
Лучше блокировать поворот или сохранять состояние через ViewModel?
Зависит от приложения. Если дизайн рассчитан только на портрет — блокировка через манифест проще и надёжнее. Если приложение должно работать на планшетах и в горизонтальном режиме, правильнее использовать ViewModel и сохранение состояния, не запрещая поворот.