Ваше приложение отлично работает на телефонах в книжной ориентации, поэтому вы ограничили его использование только этим режимом. Но вы видите возможность сделать больше на больших экранах в альбомной ориентации.
Как сделать так, чтобы на маленьких экранах приложение работало только в портретной ориентации, а на больших – и в альбомной?
Рекомендации
Лучшие приложения учитывают предпочтения пользователей, например ориентацию устройства.
В рекомендациях по обеспечению качества адаптивных приложений указано, что приложения должны поддерживать все конфигурации устройств, включая портретную и альбомную ориентацию, многооконный режим, а также сложенное и разложенное состояние складных устройств. Приложения должны оптимизировать макеты и пользовательские интерфейсы для разных конфигураций, а также сохранять и восстанавливать состояние при изменении конфигурации.
Этот рецепт – временная мера, которая позволяет добавить поддержку больших экранов. Используйте этот рецепт, пока не улучшите приложение, чтобы оно полностью поддерживало все конфигурации устройств.
Ингредиенты
screenOrientation– настройка манифеста приложения, которая позволяет указать, как приложение реагирует на изменение ориентации устройства.Activity#setRequestedOrientation()– метод, с помощью которого можно изменить ориентацию приложения во время выполнения.LocalConfiguration– локальный поставщик composable-функций, который предоставляет текущее устройствоConfiguration, позволяя считывать размеры экрана в DP.LaunchedEffect– API побочных эффектов Compose, который запускает блок кода при изменении ключа (в данном случае – при изменении конфигурации).
Шаги
Включите в манифесте приложения обработку изменений ориентации по умолчанию. Затем во время выполнения используйте Jetpack Compose, чтобы динамически ограничить ориентацию портретной на компактных экранах (телефонах), разрешив при этом все ориентации на больших экранах.
1. Укажите ориентацию в манифесте приложения
Вы можете не объявлять элемент screenOrientation в манифесте приложения (в этом случае по умолчанию будет использоваться ориентация unspecified) или задать ориентацию экрана fullUser. Если пользователь не заблокировал поворот экрана на основе датчиков, приложение будет поддерживать все ориентации устройства.
<activity
android:name=".MyActivity"
android:screenOrientation="fullUser">
Разница между unspecified и fullUser незначительна, но важна. Если вы не объявите значение screenOrientation, система выберет ориентацию, а правило, которое система использует для определения ориентации, может отличаться от устройства к устройству. С другой стороны, значение fullUser больше соответствует поведению, заданному пользователем для устройства: если пользователь заблокировал поворот на основе датчика, приложение следует его предпочтениям. В противном случае система разрешает любую из четырех возможных ориентаций экрана (книжную, альбомную, обратную книжную или обратную альбомную). Подробнее android:screenOrientation…
2. Динамически ограничивайте ориентацию в Compose
В Jetpack Compose можно реактивно считывать текущие размеры экрана в DP из LocalConfiguration.current и использовать LaunchedEffect, чтобы обновлять ориентацию действия при каждом изменении конфигурации.
Если ширина или высота экрана меньше 600dp (соответствует компактной контрольной точке для телефонов), ограничьте ориентацию портретной. В противном случае разрешите системе поворачивать приложение в соответствии с предпочтениями пользователя (unspecified или fullUser).
Ниже приведен полный код, который можно скомпилировать.
val configuration = LocalConfiguration.current val context = LocalActivity.current LaunchedEffect(configuration) { val activity = context ?: return@LaunchedEffect // Determine if screen is compact (phone-sized) in either width or height val isCompact = configuration.screenWidthDp < 600 || configuration.screenHeightDp < 600 activity.requestedOrientation = if (isCompact) { ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } else { ActivityInfo.SCREEN_ORIENTATION_FULL_USER } }
Добавив логику в блок LaunchedEffect(configuration), вы сможете реактивно переопределять настройки ориентации при каждом изменении конфигурации приложения, например когда размер действия изменяется, перемещается между дисплеями или когда складное устройство складывается или раскладывается.
Подробнее о том, когда происходят изменения конфигурации и когда они вызывают повторное создание действия, рассказывается в статье Обработка изменений конфигурации.
Результаты
Теперь приложение должно оставаться в портретной ориентации на маленьких экранах независимо от поворота устройства. На больших экранах приложение должно поддерживать горизонтальную и вертикальную ориентацию.
Дополнительные ресурсы
Чтобы узнать, как обновить приложение, чтобы оно поддерживало все конфигурации устройств, ознакомьтесь со следующими материалами:
- Поддержка экранов разных размеров
- Как обрабатывать изменения конфигурации
- Сохранение состояний пользовательского интерфейса