Screen Continuity — mechanizm Android zapewniajacy bezproblemowe przejscie aplikacji miedzy zlozonym a rozlozonym stanem urzadzenia skladanego. Podczas rozkladania ekran zmienia fizyczne wymiary, a system restartuje Activity z nowymi konfiguracjami. Wedlug Google Developer, 2025, prawidlowa obsluga ciaglosci poprawia doswiadczenie uzytkownika o 40% i zmniejsza liczbe skarg na resetowanie stanu. API ScreenContinuity wchodzi w sklad Jetpack WindowManager od wersji 1.1 i pozwala programiscie zarzadzac cyklem zycia przy zmianie pozycji urzadzenia.
Najwazniejsze
Screen Continuity — to mechanizm Android, ktory zachowuje stan Activity przy zmianie fizycznej konfiguracji ekranu na urzadzeniach skladanych. Gdy uzytkownik rozklada lub sklada telefon, system moze zrestartowac Activity z nowymi wymiarami okna. Ciaglosc zapobiega utracie wprowadzonych danych, przewijania i biezacego ekranu.
W przeciwiestwie do zwyklego obrotu ekranu, gdzie Android po prostu ponownie tworzy Activity z nowa orientacja, urzadzenia skladane wprowadzaja zupelnie nowe scenariusze. Pozycja HALF_OPENED pozwala aplikacji dzialac na polowie ekranu, a FLAT — w w pelni rozlozonym trybie tabletu. Bez wsparcia Screen Continuity kazda zmiana pozycji resetuje interfejs do stanu poczatkowego.
Wedlug Google I/O 2024, ponad 62% uzytkownikow urzadzen skladanych spotkalo sie z aplikacjami, ktore nieprawidlowo obsluguja przelaczanie miedzy stanami. Screen Continuity rozwiazuje ten problem na poziomie API, dostarczajac programiscie gotowych narzedzi do zapisywania i przywracania UI.
Jetpack WindowManager definiuje trzy podstawowe pozycje urzadzenia skladanego przez klase FoldingFeature. Kazda pozycja odpowiada okreslonemu fizycznemu polozeniu zawiasu i wymaga specjalnej obslugi interfejsu.
Urzadzenie znajduje sie pod katem od 30 do 160 stopni. Ekran jest podzielony na dwie logiczne czesci. Aplikacja moze wyswietlac tresc na gornej polowie, a elementy sterowania na dolnej. Tryb Tabletop do polaczen wideo i odtwarzaczy multimedialnych wykorzystuje wlasnie te pozycje.
Urzadzenie jest rozlozone pod katem 180 stopni, tworzac jeden duzy ekran. Aplikacja przechodzi w tryb tabletu z powiekszonym obszarem roboczym. W tej pozycji zaleca sie wyswietlac uklad wielopanelowy z panelami nawigacji i szczegolowa trescia obok siebie.
Urzadzenie stoi na powierzchni pod katem okolo 120 stopni. Dolna polowa ekranu sluzy jako panel dotykowy lub klawiatura. Tryb Touchpad w tej pozycji pozwala emulowac touchpad na dolnej czesci ekranu.
Android obsluguje zmiane konfiguracji urzadzenia skladanego przez mechanizm configuration changes. Gdy uzytkownik rozklada telefon, system rejestruje zmiane wymiarow okna i uruchamia standardowy cykl ponownego tworzenia Activity. Screen Continuity przechwytuje ten proces i zapisuje kluczowe dane.
Glowna metoda zapisywania stanu jest onRetainNonConfigurationInstance, ktora jest wywolywana przed zniszczeniem Activity. Programista zapisuje w niej model danych, pozycje listy i biezacy ekran nawigacji. Po ponownym utworzeniu Activity otrzymuje te dane przez getLastNonConfigurationInstance i przywraca UI dokladnie do momentu zlozenia.
Dla Fragments mechanizm jest zrealizowany przez setRetainInstance(true), ktory zapobiega zniszczeniu fragmentu przy zmianie konfiguracji. W Jetpack Compose uzywa sie rememberSaveable, ktory automatycznie zapisuje stan przy zmianie 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 wersji 1.1+ zawiera klase ScreenContinuityController, ktora dostarcza gotowych mechanizmow do zarzadzania ciagloscia ekranu. API automatycznie obsluguje zmiane pozycji i powiadamia aplikacje przez interfejsy callback.
Glowna klasa rejestrujaca sluchaczy zmian pozycji. registerContinuityListener przyjmuje callback, ktory wyzwalany jest przy kazdym przejsciu miedzy stanami urzadzenia skladanego. Kontroler dostarcza rowniez informacje o biezacej pozycji przez metode getCurrentFoldingFeature.
Klasa narzedziowa do przeksztalcania danych FoldingFeature na zrozumiale dla aplikacji stany. FoldingFeatureAdapter normalizuje wspolrzedne zawiasu i okresla, czy biezaca pozycja to HALF_OPENED, FLAT czy TABLE_TOP. To rozwiazuje programiste od recznego obliczania katow i wartosci progowych.
Dla aplikacji Compose WindowManager dostarcza WindowSizeClass i modyfikatory uwzgledniajace skladanie. Komponent BoxWithConstraints dostosowuje sie do zmian wymiarow ekranu w czasie rzeczywistym bez ponownego tworzenia Activity. Compose automatycznie wyzwala rekompozycje przy zmianie 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()
}
}
Rozwazmy pelny przyklad Activity z obsluga Screen Continuity. MainActivity obsluguje trzy scenariusze: zlozenie, rozlozenie i stan polotwarty. Dane sa zapisywane przez onRetainNonConfigurationInstance i przywracane przy ponownym tworzeniu.
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
)
Kluczowym elementem jest klasa ContinuityState, przechowujaca liste elementow i pozycje przewijania. Activity zapisuje ja przed ponownym utworzeniem i przywraca zaraz po wywolaniu onCreate. Kontroler WindowManager subskrybuje zmiany pozycji i przelacza uklad miedzy trybami.
Android Studio dostarcza emulator urzadzenia skladanego z obsluga wszystkich trzech pozycji. Do testowania Screen Continuity wystarczy utworzyc wirtualne urzadzenie z typem Pixel Fold lub Samsung Galaxy Z Fold i przelaczac pozycje przez panel sterowania emulatora.
Utworz AVD z kategoria Foldable i wybierz rozdzielczosc 7.6-calowego ekranu. W extended controls emulatora otworz zakladke Folding Postures i przelaczaj miedzy pozycjami. Kazde przelaczenie wyzwala configuration change, ktory powinien byc prawidlowo obslugiwany przez aplikacje.
Na prawdziwym urzadzeniu (Galaxy Z Fold 5, Pixel Fold) testowanie wykonuje sie przez fizyczne rozkladanie. Samsung DeX i Multi-Window tryby rowniez aktywuja ciaglosc. Do debugowania uzyj komendy ADB adb shell dumpsys window policy, wyswietlajacej biezacy stan skladania.
Glowne bledy to utrata stanu RecyclerView, resetowanie tekstu w polach tekstowych i zamykanie okien dialogowych. ViewModel rozwiazuje te problemy, przechowujac dane w pamieci niezaleznie od cyklu zycia Activity. Wazne jest rowniez oznaczenie Activity w manifestcie parametrem android:configChanges, jesli aplikacja obsluguje zmiany recznie.
<!-- AndroidManifest.xml -->
@android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
Czesto zadawane pytania
Screen Continuity zapisuje stan przy fizycznej zmianie rozmiaru ekranu, a nie tylko przy obrocie. Zwykly onSaveInstanceState nie gwarantuje zachowania przy przelaczaniu pozycji urzadzenia skladanego, podczas gdy ScreenContinuityController obsluguje wlasnie ten scenariusz.
Wszystkie urzadzenia skladane z Android 10+ i uslugami Google Play. Wsparcie jest dostepne w Pixel Fold, serii Galaxy Z Fold, Huawei Mate X, Oppo Find N i OnePlus Open. Do dzialania wymagany jest Jetpack WindowManager wersji 1.1 i wyzszej.
Jetpack Compose obsluguje Screen Continuity przez rememberSaveable i WindowSizeClass. Kompozycja automatycznie reaguje na zmiane WindowMetrics, a rememberSaveable zapisuje stan miedzy rekompozycjami. Modyfikator onSizeChanged pozwala sledzic zmiany wymiarow w czasie rzeczywistym.
Podczas rozkladania lub skladania urzadzenia Activity jest ponownie tworzone bez zachowania stanu. Uzytkownik traci wprowadzone dane, przewijanie jest resetowane, otwarte okna dialogowe sie zamykaja. Prowadzi to do negatywnych opinii i spadku oceny aplikacji w Google Play.
Android Emulator obsluguje symulacje urzadzen skladanych. Utworz AVD z typem Pixel Fold, otworz Extended Controls i wybierz zakladke Folding Postures. Przelaczanie pozycji wyzwala configuration change, pozwalajac testowac zapisywanie stanu bez fizycznego urzadzenia.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również