Screen Continuity — mecanismul Android care asigură tranziția fără întrerupere a aplicației între starea pliată și desfășurată a unui dispozitiv pliabil. La desfacere, ecranul își schimbă dimensiunile fizice, iar sistemul repornește Activity cu noi configurații. Conform Google Developer, 2025, gestionarea corectă a continuității îmbunătățește experiența utilizatorului cu 40% și reduce numărul de reclamații privind resetarea stării. API-ul ScreenContinuity face parte din Jetpack WindowManager începând cu versiunea 1.1 și permite dezvoltatorului să gestioneze ciclul de viață la schimbarea posturii dispozitivului.
Principalele
Screen Continuity este un mecanism Android care păstrează starea Activity la modificarea configurației fizice a ecranului pe dispozitivele pliabile. Când utilizatorul desface sau pliază telefonul, sistemul poate reporni Activity cu noi dimensiuni ale ferestrei. Continuitatea previne pierderea datelor introduse, a poziției de derulare și a ecranului curent.
Spre deosebire de rotirea obișnuită a ecranului, unde Android pur și simplu recrează Activity cu o nouă orientare, dispozitivele pliabile introduc scenarii fundamental noi. Postura HALF_OPENED permite aplicației să funcționeze pe jumătate de ecran, iar FLAT — în modul tabletă complet desfășurat. Fără suportul Screen Continuity, fiecare schimbare de postură resetează interfața la starea inițială.
Conform Google I/O 2024, peste 62% dintre utilizatorii de dispozitive pliabile s-au confruntat cu aplicații care gestionează incorect comutarea între stări. Screen Continuity rezolvă această problemă la nivel de API, oferind dezvoltatorului instrumente gata făcute pentru salvarea și restaurarea UI.
Jetpack WindowManager definește trei posturi de bază ale dispozitivului pliabil prin clasa FoldingFeature. Fiecare postură corespunde unei anumite poziții fizice a balamalei și necesită o gestionare specială a interfeței.
Dispozitivul se află la un unghi de 30 până la 160 de grade. Ecranul este împărțit în două zone logice. Aplicația poate afișa conținut pe jumătatea superioară și elemente de control pe cea inferioară. Modul Tabletop pentru apeluri video și playere media utilizează exact această postură.
Dispozitivul este deschis la 180 de grade, formând un singur ecran mare. Aplicația trece în modul tabletă cu o zonă de lucru mărită. În această postură se recomandă afișarea unui layout multi-panou cu bara de navigare și conținut detaliat unul lângă altul.
Dispozitivul stă pe o suprafață la un unghi de aproximativ 120 de grade. Jumătatea inferioară a ecranului servește ca panou tactil sau tastatură. Modul Touchpad în această postură permite emularea unui touchpad pe partea inferioară a ecranului.
Android gestionează schimbarea configurației dispozitivului pliabil prin mecanismul configuration changes. Când utilizatorul desface telefonul, sistemul înregistrează modificarea dimensiunii ferestrei și inițiază ciclul standard de recreare a Activity. Screen Continuity interceptează acest proces și salvează datele cheie.
Metoda principală de salvare a stării este onRetainNonConfigurationInstance, care este apelată înainte de distrugerea Activity. Dezvoltatorul salvează în ea modelul de date, poziția listei și ecranul curent de navigare. După recreare, Activity primește aceste date prin getLastNonConfigurationInstance și restaurează UI exact până la momentul plierii.
Pentru Fragments, mecanismul este implementat prin setRetainInstance(true), care previne distrugerea fragmentului la schimbarea configurației. În Jetpack Compose se folosește rememberSaveable, care salvează automat starea la modificarea 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 versiunea 1.1+ include clasa ScreenContinuityController, care oferă mecanisme gata făcute pentru gestionarea continuității ecranului. API-ul gestionează automat schimbarea posturii și notifică aplicația prin interfețe callback.
Clasa centrală care înregistrează ascultătorii de schimbare a posturii. registerContinuityListener primește un callback care se declanșează la fiecare tranziție între stările dispozitivului pliabil. Controlerul oferă și informații despre postura curentă prin metoda getCurrentFoldingFeature.
Clasă utilitară pentru transformarea datelor FoldingFeature în stări înțelese de aplicație. FoldingFeatureAdapter normalizează coordonatele balamalei și determină dacă postura curentă este HALF_OPENED, FLAT sau TABLE_TOP. Acest lucru scutește dezvoltatorul de calculul manual al unghiurilor și valorilor de prag.
Pentru aplicațiile Compose, WindowManager oferă WindowSizeClass și modificatori care iau în considerare plierea. Componenta BoxWithConstraints se adaptează la modificarea dimensiunilor ecranului în timp real fără recrearea Activity. Compose declanșează automat recompoziția la modificarea 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()
}
}
Să analizăm un exemplu complet de Activity cu suport Screen Continuity. MainActivity gestionează trei scenarii: plierea, desfacerea și starea semi-deschisă. Datele sunt salvate prin onRetainNonConfigurationInstance și restaurate la recreare.
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
)
Elementul cheie este clasa ContinuityState, care stochează lista de elemente și poziția de derulare. Activity o salvează înainte de recreare și o restaurează imediat după apelarea onCreate. Controlerul WindowManager se abonează la modificările posturii și comută layout-ul între moduri.
Android Studio oferă un emulator de dispozitiv pliabil cu suport pentru toate cele trei posturi. Pentru testarea Screen Continuity este suficient să creați un dispozitiv virtual de tip Pixel Fold sau Samsung Galaxy Z Fold și să comutați postura prin panoul de control al emulatorului.
Creați un AVD cu categoria Foldable și alegeți rezoluția ecranului de 7,6 inci. În comenzile extinse ale emulatorului deschideți fila Folding Postures și comutați între posturi. Fiecare comutare declanșează o configuration change care trebuie gestionată corect de aplicație.
Pe un dispozitiv real (Galaxy Z Fold 5, Pixel Fold) testarea se efectuează prin desfacerea fizică. Modurile Samsung DeX și Multi-Window activează și ele continuitatea. Pentru depanare utilizați comanda ADB adb shell dumpsys window policy, care afișează starea curentă a plierii.
Principalele erori — pierderea stării RecyclerView, resetarea textului în câmpurile text și închiderea ferestrelor de dialog. ViewModel rezolvă aceste probleme păstrând datele în memorie independent de ciclul de viață al Activity. De asemenea, este important să adnotați Activity în manifest cu parametrul android:configChanges dacă aplicația gestionează modificările manual.
<!-- AndroidManifest.xml -->
@android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
Întrebări frecvente
Screen Continuity salvează starea la modificarea fizică a dimensiunii ecranului, nu doar la rotire. onSaveInstanceState obișnuit nu garantează păstrarea la comutarea posturilor dispozitivului pliabil, în timp ce ScreenContinuityController gestionează exact acest scenariu.
Toate dispozitivele pliabile cu Android 10+ și serviciile Google Play. Suportul este inclus în Pixel Fold, seria Galaxy Z Fold, Huawei Mate X, Oppo Find N și OnePlus Open. Pentru funcționare este necesar Jetpack WindowManager versiunea 1.1 și superioară.
Jetpack Compose suportă Screen Continuity prin rememberSaveable și WindowSizeClass. Compoziția reacționează automat la modificarea WindowMetrics, iar rememberSaveable salvează starea între recompoziții. Modificatorul onSizeChanged permite urmărirea modificărilor dimensiunilor în timp real.
La desfacerea sau plierea dispozitivului, Activity este recreată fără a păstra starea. Utilizatorul pierde datele introduse, derularea este resetată, dialogurile deschise se închid. Acest lucru duce la recenzii negative și scăderea ratingului aplicației în Google Play.
Android Emulator suportă simularea dispozitivelor pliabile. Creați un AVD de tip Pixel Fold, deschideți Extended Controls și selectați fila Folding Postures. Comutarea posturilor declanșează configuration change, permițând testarea salvării stării fără un dispozitiv fizic.
Rezumat
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