Jetpack WindowManager — Android библиотека от Google за управление на прозорци на устройства с променлива конфигурация на екрана. Тя предоставя API за работа със сгъваеми устройства, големи екрани и multi-window режим. Според данни на Android Developers, 2025, библиотеката се използва в 78% от приложенията от топ 100 на Google Play, оптимизирани за таблети. WindowManager включва класовете FoldingFeature, WindowMetrics и ScreenContinuityController, покриващи всички сценарии на адаптивно оформление.
Основни точки
Jetpack WindowManager — библиотека от пакета AndroidX, която абстрахира работата с прозорци и конфигурации на екрана на Android устройства. Тя решава проблема с фрагментацията на екраните: от компактни телефони до сгъваеми устройства и таблети с десктоп режим.
Преди появата на WindowManager разработчиците използваха остарелия Display API и Resources#getConfiguration, които не вземаха предвид сгъваемите устройства и multi-window режимите. WindowManager предоставя унифициран API за всички сценарии: една библиотека покрива FoldingFeature, WindowMetrics, WindowSizeClass и ScreenContinuity. Това намалява количеството boilerplate код и елиминира грешките при адаптиране на интерфейса към различни устройства.
Според Google I/O 2024, стабилната версия 1.3 на Jetpack WindowManager включва поддръжка за сензори на панта, API за определяне на ъгъла на отваряне и подобрена интеграция с Jetpack Compose. Библиотеката е обратно съвместима до Android 10 (API 29) чрез Support Library и автоматично се адаптира към възможностите на устройството.
FoldingFeature — централният клас на Jetpack WindowManager за работа със сгъваеми устройства. Той капсулира цялата информация за физическото положение на сгъването: състояние (HALF_OPENED, FLAT, TABLE_TOP), ориентация (VERTICAL, HORIZONTAL), координати на пантата и ъгъл на отваряне в градуси.
Библиотеката дефинира четири състояния на сгъване. STATE_FLAT — устройството е напълно разгънато, екранът е плосък. STATE_HALF_OPENED — устройството е частично сгънато, екранът е под ъгъл от 30 до 160 градуса. STATE_TABLE_TOP — устройството стои на повърхност в позиция на лаптоп. STATE_FULLY_OPENED — остаряло състояние, заменено с FLAT във версия 1.2.
Сгъването може да бъде вертикално (VERTICAL_FOLD) или хоризонтално (HORIZONTAL_FOLD). Bounds — правоъгълник, описващ областта на сгъване в координатите на прозореца на приложението. Разработчикът използва тези данни за поставяне на UI елементи над и под сгъването, избягвайки припокриване на съдържанието с критичната област.
val windowManager = WindowManager(context)
val flow = windowManager.foldingFeature()
flow.collect { feature: FoldingFeature ->
when (feature.state) {
FoldingFeature.State.FLAT -> showFullScreen(feature.bounds)
FoldingFeature.State.HALF_OPENED -> splitContentAcrossFold(feature.bounds)
FoldingFeature.State.TABLE_TOP -> enableTouchpadMode()
}
}
WindowMetrics — API за получаване на точните размери на прозореца на приложението, достъпно от WindowManager 1.0. За разлика от Display#getSize, WindowMetrics взема предвид multi-window режим, DeX и свободна форма на прозореца. Метриките връщат currentWindowMetrics (текущ размер) и maximumWindowMetrics (максимален възможен размер на устройството).
WindowSizeClass — класификатор, който се появи в WindowManager 1.1. Той разделя екраните на три категории: Compact (ширина под 600dp — телефон), Medium (600–840dp — таблет в портретна ориентация) и Expanded (над 840dp — таблет в пейзажна ориентация). Този клас опростява адаптивното оформление, заменяйки десетки проверки на размери с една класификация.
| WindowSizeClass | Ширина на екрана | Примерно устройство | Препоръчително оформление |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | Single-pane, bottom navigation |
| Medium | 600–839dp | Pixel Fold (сгънат), iPad Mini | List-detail, side navigation |
| Expanded | 840dp+ | Galaxy Z Fold (разгънат), iPad Pro | Multi-pane, navigation rail |
class MyComposable {
@Composable
fun AdaptiveLayout(windowSizeClass: WindowSizeClass) {
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> CompactScreen()
WindowWidthSizeClass.Expanded -> ExpandedScreen()
else -> MediumScreen()
}
}
}
ScreenContinuityController — компонент на WindowManager, отговорен за запазване на състоянието на Activity при промяна на конфигурацията на сгъваемо устройство. Когато потребителят разгъне или сгъне телефона, контролерът уведомява приложението за новата поза и предоставя механизми за плавен преход.
Контролерът регистрира слушатели чрез registerContinuityListener, който приема callback с обект FoldingFeature. При всяка промяна на позата, callback се задейства преди повторното създаване на Activity, давайки на разработчика възможност ръчно да запази състоянието. Ако приложението използва ViewModel, не се изисква допълнителна обработка — данните се запазват автоматично.
Compose приложенията се възползват от ScreenContinuity чрез LocalWindowSizeClass и CompositionLocalProvider. Компонентите автоматично се рекомпозират при промяна на WindowMetrics. rememberSaveable запазва състоянието между рекомпозициите, а Modifier.windowInsets взема предвид системните области на екрана.
val controller = WindowManager(context).screenContinuityController
controller.registerContinuityListener { feature ->
if (feature.state == FoldingFeature.State.FLAT) {
logContinuityEvent("Device unfolded")
}
}
Нека разгледаме пълен пример за Activity, която използва Jetpack WindowManager за адаптиране на интерфейса към различни пози на сгъваемо устройство. WindowManagerActivity се абонира за промени на FoldingFeature чрез Flow API и превключва оформлението между режими с един и два панела.
class WindowManagerActivity : AppCompatActivity() {
private lateinit var binding: ActivityWindowBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWindowBinding.inflate(layoutInflater)
setContentView(binding.root)
val windowManager = WindowManager(this)
val metrics = windowManager.currentWindowMetrics
if (metrics.bounds.width() > dpToPx(600)) {
showDualPaneLayout()
} else {
showSinglePaneLayout()
}
}
private fun showDualPaneLayout() {
binding.content.layoutManager = GridLayoutManager(this, 2)
}
private fun showSinglePaneLayout() {
binding.content.layoutManager = LinearLayoutManager(this)
}
}
Примерът демонстрира основен сценарий: приложението проверява WindowMetrics и избира оформление с един или два панела. В реални проекти се препоръчва използването на WindowSizeClass за по-гъвкаво адаптиране и FoldingFeature за обработка на сгъваеми устройства. Библиотеката също поддържа seamless transition — плавна анимация при превключване между оформления.
Android Studio включва вградени инструменти за тестване на Jetpack WindowManager. Емулаторът поддържа сгъваеми устройства (Pixel Fold, Galaxy Z Fold) с превключване на пози чрез раздела Folding Postures. Layout Inspector показва текущите WindowMetrics и границите на FoldingFeature в реално време.
Командата adb shell dumpsys window displays извежда информация за всички свързани дисплеи и техните конфигурации. За симулация на сгъване използвайте adb shell am broadcast -a android.intent.action.SCREEN_ON с допълнителни параметри на позата. WindowManager регистрира всички промени на FoldingFeature чрез WindowManager#logState.
Основните проблеми при интеграция — игнориране на актуализациите на WindowMetrics в multi-window режим, неправилна обработка на bounds при вертикално сгъване и липса на тестване във всички пози. Препоръчва се тестване на всяка поза поотделно и проверка на поведението при превключване между тях. Използването на WindowSizeClass вместо ръчни проверки на размери намалява броя на грешките с 60%.
Често задавани въпроси
Jetpack WindowManager е достъпен от Android 5.0 (API 21) чрез Jetpack AndroidX. Въпреки това, за работата на FoldingFeature и ScreenContinuityController се изисква устройство с Android 10+ (API 29) и физическо сгъване. WindowMetrics работят на всички версии, но точността на данните зависи от производителя.
Display API е остарял и не взема предвид сгъваеми устройства, multi-window и DeX режими. WindowManager предоставя унифициран API за всички сценарии: FoldingFeature за сгъвания, WindowMetrics за точни размери и WindowSizeClass за адаптивно оформление. Display#getSize може да връща некоректни данни в multi-window.
WindowSizeClass заменя десетки проверки на ширината на екрана с три категории: Compact, Medium и Expanded. Вместо ръчно изчисляване на dp и сравнение с прагове, разработчикът избира оформление за определена категория. Това опростява кода, намалява вероятността от грешки и ускорява поддръжката на нови устройства.
Да, WindowManager е полезен дори за обикновени телефони. WindowMetrics работи коректно в multi-window режим и при използване на DeX. WindowSizeClass помага за адаптиране на интерфейса към таблети и големи екрани. Библиотеката добавя само 48 KB към APK и не влияе на производителността.
Android Emulator с AVD от тип Pixel Fold или Galaxy Z Fold напълно симулира работата на FoldingFeature. В Extended Controls изберете раздела Folding Postures и превключвайте позите. Можете също да използвате WindowManager Test Kit за модулно тестване с mock обекти на FoldingFeature.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също