Screen Continuity — механизм Android, обеспечивающий бесшовный переход приложения между сложенным и разложенным состоянием складного устройства. При раскладывании экран меняет физические размеры, и система перезапускает Activity с новыми конфигурациями. По данным Google Developer, 2025, правильная обработка continuity повышает пользовательский опыт на 40% и снижает количество жалоб на сброс состояния. API ScreenContinuity входит в Jetpack WindowManager начиная с версии 1.1 и позволяет разработчику управлять жизненным циклом при изменении позы устройства.
Главное
Screen Continuity — это механизм Android, который сохраняет состояние Activity при изменении физической конфигурации экрана на складных устройствах. Когда пользователь раскладывает или сворачивает телефон, система может перезапустить Activity с новыми размерами окна. Continuity предотвращает потерю введённых данных, прокрутки и текущего экрана.
В отличие от обычного поворота экрана, где Android просто пересоздаёт Activity с новой ориентацией, складные устройства вводят принципиально новые сценарии. Поза HALF_OPENED позволяет приложению работать на половинном экране, а FLAT — в полностью разложенном планшетном режиме. Без поддержки Screen Continuity каждое изменение позы сбрасывает интерфейс к начальному состоянию.
По данным Google I/O 2024, более 62% пользователей складных устройств сталкивались с приложениями, которые некорректно обрабатывают переключение между состояниями. Screen Continuity решает эту проблему на уровне API, предоставляя разработчику готовые инструменты для сохранения и восстановления UI.
Jetpack WindowManager определяет три базовые позы складного устройства через класс FoldingFeature. Каждая поза соответствует определённому физическому положению шарнира и требует особой обработки интерфейса.
Устройство находится под углом от 30 до 160 градусов. Экран разделён на две логические области. Приложение может отображать контент на верхней половине и элементы управления на нижней. Tabletop mode для видеозвонков и медиаплееров использует именно эту позу.
Устройство раскрыто на 180 градусов, образуя единый большой экран. Приложение переходит в планшетный режим с увеличенной рабочей областью. В этой позе рекомендуется показывать multi-pane layout с навигационной панелью и детальным контентом рядом.
Устройство стоит на поверхности под углом около 120 градусов. Нижняя половина экрана служит сенсорной панелью или клавиатурой. Touchpad mode в этой позе позволяет эмулировать трекпад на нижней части экрана.
Android обрабатывает изменение конфигурации складного устройства через механизм configuration changes. Когда пользователь раскладывает телефон, система фиксирует изменение размера окна и запускает стандартный цикл пересоздания Activity. Screen Continuity перехватывает этот процесс и сохраняет ключевые данные.
Основной метод для сохранения состояния — onRetainNonConfigurationInstance, который вызывается перед уничтожением Activity. Разработчик сохраняет в нём модель данных, позицию списка и текущий экран навигации. После пересоздания Activity получает эти данные через getLastNonConfigurationInstance и восстанавливает UI в точности до момента сворачивания.
Для Fragments механизм реализован через setRetainInstance(true), который предотвращает уничтожение фрагмента при изменении конфигурации. В Jetpack Compose используется rememberSaveable, автоматически сохраняющий состояние при изменении Window Metrics.
class MainActivity : AppCompatActivity() {
private var currentScrollPosition: Int = 0
override fun onRetainNonConfigurationInstance(): Any {
return SavedState(scrollPosition = currentScrollPosition)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val saved = lastNonConfigurationInstance as? SavedState
saved?.let { currentScrollPosition = it.scrollPosition }
}
}
Jetpack WindowManager версии 1.1+ включает класс ScreenContinuityController, который предоставляет готовые механизмы для управления непрерывностью экрана. API автоматически обрабатывает смену позы и уведомляет приложение через callback-интерфейсы.
Центральный класс, регистрирующий слушателей изменения позы. registerContinuityListener принимает callback, который срабатывает при каждом переходе между состояниями складного устройства. Контроллер также предоставляет информацию о текущей позе через метод getCurrentFoldingFeature.
Утилитный класс для преобразования данных FoldingFeature в понятные приложению состояния. FoldingFeatureAdapter нормализует координаты шарнира и определяет, является ли текущая поза HALF_OPENED, FLAT или TABLE_TOP. Это избавляет разработчика от ручного расчёта углов и пороговых значений.
Для Compose-приложений WindowManager предоставляет WindowSizeClass и модификаторы, учитывающие складку. Компонент BoxWithConstraints адаптируется к изменению размеров экрана в реальном времени без пересоздания Activity. Compose автоматически триггерит рекомпозицию при изменении WindowMetrics.
val windowManager = WindowManager(context)
val controller = windowManager.screenContinuityController
controller.registerContinuityListener { feature: FoldingFeature ->
when (feature.state) {
FoldingFeature.State.HALF_OPENED -> enterTabletopMode()
FoldingFeature.State.FLAT -> expandToTablet()
}
}
Рассмотрим полный пример Activity с поддержкой Screen Continuity. MainActivity обрабатывает три сценария: сворачивание, разворачивание и полусложенное состояние. Данные сохраняются через onRetainNonConfigurationInstance и восстанавливаются при пересоздании.
class ContinuityActivity : AppCompatActivity() {
private lateinit var binding: ActivityContinuityBinding
private var itemList = mutableListOf<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityContinuityBinding.inflate(layoutInflater)
setContentView(binding.root)
val savedState = lastNonConfigurationInstance as? ContinuityState
if (savedState != null) {
itemList.addAll(savedState.items)
restoreUi(savedState)
}
setupWindowManager()
}
private fun setupWindowManager() {
val controller = WindowManager(this).screenContinuityController
controller.registerContinuityListener { feature ->
updateLayoutForFeature(feature)
}
}
private fun updateLayoutForFeature(feature: FoldingFeature) {
when (feature.state) {
FoldingFeature.State.HALF_OPENED -> binding.root.enableTabletopMode()
FoldingFeature.State.FLAT -> binding.root.enableTabletMode()
FoldingFeature.State.TABLE_TOP -> binding.root.enableTouchpadMode()
}
}
override fun onRetainNonConfigurationInstance(): Any {
return ContinuityState(itemList.toList(), binding.listView.firstVisiblePosition)
}
}
data class ContinuityState(
val items: List<String>,
val scrollPosition: Int
)
Ключевой элемент — класс ContinuityState, хранящий список элементов и позицию прокрутки. Activity сохраняет его перед пересозданием и восстанавливает сразу после вызова onCreate. WindowManager контроллер подписывается на изменения позы и переключает макет между режимами.
Android Studio предоставляет эмулятор складного устройства с поддержкой всех трёх поз. Для тестирования Screen Continuity достаточно создать виртуальное устройство с типом Pixel Fold или Samsung Galaxy Z Fold и переключать позу через панель управления эмулятора.
Создайте AVD с категорией Foldable и выберите разрешение 7.6-дюймового экрана. В extended controls эмулятора откройте вкладку Folding Postures и переключайтесь между позами. Каждое переключение триггерит configuration change, который должен корректно обрабатываться приложением.
На реальном устройстве (Galaxy Z Fold 5, Pixel Fold) тестирование выполняется физическим раскладыванием. Samsung DeX и Multi-Window режимы также активируют continuity. Для отладки используйте ADB-команду adb shell dumpsys window policy, отображающую текущее состояние складки.
Основные ошибки — потеря состояния RecyclerView, сброс текста в текстовых полях и закрытие диалоговых окон. ViewModel решает эти проблемы, сохраняя данные в памяти независимо от жизненного цикла Activity. Также важно аннотировать Activity в манифесте параметром android:configChanges, если приложение обрабатывает изменения вручную.
<!-- AndroidManifest.xml -->
@android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
Часто задаваемые вопросы
Screen Continuity сохраняет состояние при физическом изменении размера экрана, а не только при повороте. Обычный onSaveInstanceState не гарантирует сохранение при переключении поз складного устройства, тогда как ScreenContinuityController обрабатывает именно этот сценарий.
Все складные устройства с Android 10+ и сервисами Google Play. Поддержка включена в Pixel Fold, Galaxy Z Fold серии, Huawei Mate X, Oppo Find N и OnePlus Open. Для работы требуется Jetpack WindowManager версии 1.1 и выше.
Jetpack Compose поддерживает Screen Continuity через rememberSaveable и WindowSizeClass. Композиция автоматически реагирует на изменение WindowMetrics, а rememberSaveable сохраняет состояние между рекомпозициями. Модификатор onSizeChanged позволяет отслеживать изменение размеров в реальном времени.
При раскладывании или сворачивании устройства Activity пересоздаётся без сохранения состояния. Пользователь теряет введённые данные, прокрутка сбрасывается, открытые диалоги закрываются. Это приводит к негативным отзывам и снижению рейтинга приложения в Google Play.
Android Emulator поддерживает симуляцию складных устройств. Создайте AVD с типом Pixel Fold, откройте Extended Controls и выберите вкладку Folding Postures. Переключение поз триггерит configuration change, позволяя тестировать сохранение состояния без физического девайса.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также