Jetpack WindowManager — biblioteca Android de la Google pentru gestionarea ferestrelor pe dispozitive cu configurație variabilă a ecranului. Oferă API-uri pentru lucrul cu dispozitive pliabile, ecrane mari și modul multi-window. Conform datelor Android Developers, 2025, biblioteca este utilizată în 78% din aplicațiile din top-100 Google Play optimizate pentru tablete. WindowManager include clasele FoldingFeature, WindowMetrics și ScreenContinuityController, acoperind toate scenariile de layout adaptiv.
Principalele puncte
Jetpack WindowManager — biblioteca din pachetul AndroidX care abstractizează lucrul cu ferestrele și configurațiile ecranului pe dispozitivele Android. Rezolvă problema fragmentării ecranelor: de la telefoane compacte la dispozitive pliabile și tablete cu mod desktop.
Înainte de apariția WindowManager, dezvoltatorii foloseau Display API învechit și Resources#getConfiguration, care nu luau în considerare dispozitivele pliabile și modurile multi-window. WindowManager oferă un API unificat pentru toate scenariile: o singură bibliotecă acoperă FoldingFeature, WindowMetrics, WindowSizeClass și ScreenContinuity. Aceasta reduce cantitatea de cod boilerplate și elimină bug-urile la adaptarea interfeței pentru diferite dispozitive.
Conform Google I/O 2024, versiunea stabilă 1.3 a Jetpack WindowManager include suport pentru senzori de balama, API pentru determinarea unghiului de deschidere și integrare îmbunătățită cu Jetpack Compose. Biblioteca este compatibilă invers până la Android 10 (API 29) prin Support Library și se adaptează automat la capacitățile dispozitivului.
FoldingFeature — clasa centrală a Jetpack WindowManager pentru lucrul cu dispozitive pliabile. Încapsulează toate informațiile despre poziția fizică a plierii: starea (HALF_OPENED, FLAT, TABLE_TOP), orientarea (VERTICAL, HORIZONTAL), coordonatele balamalei și unghiul de deschidere în grade.
Biblioteca definește patru stări de pliere. STATE_FLAT — dispozitivul complet desfășurat, ecranul plat. STATE_HALF_OPENED — dispozitivul parțial pliat, ecranul la un unghi între 30 și 160 de grade. STATE_TABLE_TOP — dispozitivul stă pe o suprafață în poziție de laptop. STATE_FULLY_OPENED — stare învechită, înlocuită cu FLAT în versiunea 1.2.
Plierea poate fi verticală (VERTICAL_FOLD) sau orizontală (HORIZONTAL_FOLD). Bounds — dreptunghiul care descrie zona de pliere în coordonatele ferestrei aplicației. Dezvoltatorul folosește aceste date pentru plasarea elementelor UI deasupra și dedesubtul plierii, evitând suprapunerea conținutului peste zona critică.
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 pentru obținerea dimensiunilor exacte ale ferestrei aplicației, disponibil din WindowManager 1.0. Spre deosebire de Display#getSize, WindowMetrics ia în considerare modul multi-window, DeX și forma liberă a ferestrei. Metricile returnează currentWindowMetrics (dimensiunea curentă) și maximumWindowMetrics (dimensiunea maximă posibilă pe dispozitiv).
WindowSizeClass — clasificatorul apărut în WindowManager 1.1. Împarte ecranele în trei categorii: Compact (lățime sub 600dp — telefon), Medium (600–840dp — tabletă în orientare portret) și Expanded (peste 840dp — tabletă în orientare peisaj). Această clasă simplifică layout-ul adaptiv, înlocuind zeci de verificări de dimensiuni cu o singură clasificare.
| WindowSizeClass | Lățimea ecranului | Dispozitiv exemplu | Layout recomandat |
|---|---|---|---|
| Compact | 0–599dp | Pixel 8, Galaxy S24 | Single-pane, bottom navigation |
| Medium | 600–839dp | Pixel Fold (pliat), iPad Mini | List-detail, side navigation |
| Expanded | 840dp+ | Galaxy Z Fold (desfășurat), 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 — componenta WindowManager responsabilă pentru păstrarea stării Activity la schimbarea configurației dispozitivului pliabil. Când utilizatorul desfășoară sau pliază telefonul, controlerul notifică aplicația despre noua postură și oferă mecanisme pentru o tranziție lină.
Controlerul înregistrează ascultători prin registerContinuityListener, care primește un callback cu obiectul FoldingFeature. La fiecare schimbare de postură, callback-ul se declanșează înainte de recrearea Activity, oferind dezvoltatorului posibilitatea de a salva manual starea. Dacă aplicația folosește ViewModel, nu este necesară procesare suplimentară — datele se salvează automat.
Aplicațiile Compose beneficiază de ScreenContinuity prin LocalWindowSizeClass și CompositionLocalProvider. Componentele se recompun automat la modificarea WindowMetrics. rememberSaveable păstrează starea între recompoziții, iar Modifier.windowInsets ia în considerare zonele sistemice ale ecranului.
val controller = WindowManager(context).screenContinuityController
controller.registerContinuityListener { feature ->
if (feature.state == FoldingFeature.State.FLAT) {
logContinuityEvent("Device unfolded")
}
}
Să analizăm un exemplu complet de Activity care folosește Jetpack WindowManager pentru adaptarea interfeței la diferite posturi ale dispozitivului pliabil. WindowManagerActivity se abonează la modificările FoldingFeature prin Flow API și comută layout-ul între modurile cu un singur panou și cu două panouri.
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)
}
}
Exemplul demonstrează un scenariu de bază: aplicația verifică WindowMetrics și alege un layout cu unul sau două panouri. În proiecte reale, se recomandă utilizarea WindowSizeClass pentru o adaptare mai flexibilă și FoldingFeature pentru gestionarea dispozitivelor pliabile. Biblioteca suportă și seamless transition — animație lină la comutarea între layout-uri.
Android Studio include instrumente integrate pentru testarea Jetpack WindowManager. Emulatorul suportă dispozitive pliabile (Pixel Fold, Galaxy Z Fold) cu comutarea posturilor prin fila Folding Postures. Layout Inspector afișează WindowMetrics curente și limitele FoldingFeature în timp real.
Comanda adb shell dumpsys window displays afișează informații despre toate display-urile conectate și configurațiile lor. Pentru simularea plierii, utilizați adb shell am broadcast -a android.intent.action.SCREEN_ON cu parametri suplimentari de postură. WindowManager înregistrează toate modificările FoldingFeature prin WindowManager#logState.
Principalele probleme la integrare — ignorarea actualizărilor WindowMetrics în modul multi-window, procesarea incorectă a bounds la plierea verticală și lipsa testării în toate posturile. Se recomandă testarea fiecărei posturi separat și verificarea comportamentului la comutarea între ele. Utilizarea WindowSizeClass în locul verificărilor manuale de dimensiuni reduce numărul de bug-uri cu 60%.
Întrebări frecvente
Jetpack WindowManager este disponibil începând cu Android 5.0 (API 21) prin Jetpack AndroidX. Cu toate acestea, pentru funcționarea FoldingFeature și ScreenContinuityController este necesar un dispozitiv cu Android 10+ (API 29) și pliere fizică. WindowMetrics funcționează pe toate versiunile, dar acuratețea datelor depinde de producător.
Display API este învechit și nu ia în considerare dispozitivele pliabile, modurile multi-window și DeX. WindowManager oferă un API unificat pentru toate scenariile: FoldingFeature pentru pliere, WindowMetrics pentru dimensiuni precise și WindowSizeClass pentru layout adaptiv. Display#getSize poate returna date incorecte în multi-window.
WindowSizeClass înlocuiește zeci de verificări ale lățimii ecranului cu trei categorii: Compact, Medium și Expanded. În locul calculului manual al dp și comparației cu praguri, dezvoltatorul alege layout-ul pentru o categorie specifică. Aceasta simplifică codul, reduce probabilitatea erorilor și accelerează suportul pentru noi dispozitive.
Da, WindowManager este util chiar și pentru telefoane obișnuite. WindowMetrics funcționează corect în modul multi-window și la utilizarea DeX. WindowSizeClass ajută la adaptarea interfeței pentru tablete și ecrane mari. Biblioteca adaugă doar 48 KB la APK și nu afectează performanța.
Android Emulator cu AVD de tip Pixel Fold sau Galaxy Z Fold simulează complet funcționarea FoldingFeature. În Extended Controls, selectați fila Folding Postures și comutați posturile. De asemenea, puteți utiliza WindowManager Test Kit pentru testare unitară cu obiecte mock FoldingFeature.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și