remember — egy függvény a Jetpack Compose-ban, amely lehetővé teszi az érték megőrzését a rekompozíciók között, megakadályozva az állapot visszaállítását a Composable függvény minden újraindításakor. remember nélkül a függvényben deklarált összes változó alaphelyzetbe állna minden UI-frissítéskor, instabillá és használhatatlanná téve az állapotot. A Google Android Developers, 2026 szerint a remember helyes használata a deklaratív UI-ban történő helyes állapotkezelés alapja.
Főbb pontok
remember — egy beépített Jetpack Compose függvény az androidx.compose.runtime csomagból, amely létrehoz egy objektumot, amely megőrzi értékét a Composable függvény egymást követő hívásai között. Technikailag a remember slotokkal működik — speciális memóriacellákkal, amelyek a függvényhívás minden pozíciójához vannak hozzárendelve az UI-fában. Amíg a függvény a kompozícióban marad (nem távolították el if-feltétellel), a remember minden rekompozíciókor visszaadja a mentett értéket.
A remember szintaxisa egyszerű: a kapcsos zárójelek között meg kell adni a kezdeti érték kiszámításának blokkját. A blokk csak egyszer hajtódik végre — a függvény első kompozíciójakor. Az összes későbbi rekompozíció a már mentett értéket adja vissza anélkül, hogy újra meghívná a blokkot. Ha azonban egy kulcs (key paraméter) meg van adva, a blokk újra végrehajtódik a kulcs változásakor, lehetővé téve az érték újraszámítását a bemeneti adatok alapján.
A remember nem Kotlin varázslat — ez egy egyszerű függvény key paraméterrel és számítási lambdával. Belső implementációja a Composer-t használja a slotok olvasásához és írásához. A Kotlin fordító a remember hívását látva kódot generál, amely hozzáfér az aktuális CompositionContext-hez és kezeli a slotokat. Ez azt jelenti, hogy a remember csak Composable függvényen belül vagy más, kompozíciós kontextusban lévő függvényen belül hívható meg.
A Jetpack Compose-ban a remember-nek három fő változata létezik, mindegyiknek saját célja. Az alap remember csak az aktuális folyamat memóriájában őrzi meg az értéket — képernyőelforgatáskor (config change) a Compose újra létrehozza a Composition-t, és az összes remember érték visszaáll. Az adatok megőrzéséhez konfigurációs változások és folyamatleállítás esetén a rememberSaveable-t használjuk.
rememberSaveable szerializálja az értéket Bundle-be a SavedStateHandle vagy Parcelable mechanizmuson keresztül. Ez lehetővé teszi a képernyőelforgatás, a „Tevékenységek ne mentése” hívás és akár az alkalmazás ideiglenes minimalizálásának túlélését is. A rememberSaveable azonban korlátozásokat ír elő a tárolt adatok típusára: primitíveknek, Parcelable-nak, Serializable-nak kell lenniük, vagy támogatniuk kell a Saver konvertert.
derivedStateOf — nem tárolási mechanizmus, hanem optimalizálás. Létrehoz egy State-t, amelynek értéke más State objektumok alapján kerül kiszámításra. A derivedStateOf reagál a forrásállapotok változásaira, de csak akkor számolja újra az értéket, ha vannak előfizetők. Ha az aktuális rekompozíció nem olvassa a derivedStateOf-ot, a számítás nem történik meg, ami erőforrásokat takarít meg gyakori, de senki által nem igényelt frissítéseknél.
@Composable
fun RememberVariants() {
// 1. Alap remember: a kompozíció elhagyásáig megmarad
val createdAt = remember { System.currentTimeMillis() }
// 2. rememberSaveable: túléli a képernyőelforgatást
var username by rememberSaveable { mutableStateOf("") }
// 3. derivedStateOf: csak szükség esetén számolódik
val isButtonVisible = remember {
derivedStateOf { username.length() > 3 }
}
Text("Létrehozva: $createdAt")
TextField(value = username, onValueChange = { username = it })
if (isButtonVisible.value) {
Text("A gomb megjelenik")
}
}
A választás a remember és a rememberSaveable között attól függ, hogy mennyire kritikus az adatok megőrzése konfigurációs változások esetén. Az átmeneti állapotokhoz, amelyek elvesztése elforgatáskor nem fontos (animáció, aktuális görgetési pozíció, fókusz állapota) — elég a hagyományos remember. Kritikus adatokhoz (űrlap szövege, kiválasztott elemek, jelölőnégyzetek) — használja a rememberSaveable-t.
Teljesítmény a rememberSaveable esetében alacsonyabb, mint a hagyományos remember-nél, mivel szerializációt igényel a Bundle-be. Csak azokhoz az adatokhoz használja a rememberSaveable-t, amelyeknek túl kell élniük az Activity újralétrehozását. Minden máshoz — egyszerű remember. A rememberSaveable túlzott használata lelassítja a képernyőelforgatásokat és az alkalmazások közötti váltást.
Ha olyan osztályokkal dolgozik, amelyek nem támogatják a Parcelable-t vagy Serializable-t, használja a Saver-t — egy konvertert, amely meghatározza, hogyan kell menteni és visszaállítani egy objektumot. A Savert egy lambda pár írja le: save (átalakítja az objektumot menthető típussá) és restore (visszaállítja az objektumot a mentett adatokból). A standard Saver már implementálva van a mutableStateListOf és a mutableStateMapOf számára.
| Jellemző | remember | rememberSaveable |
|---|---|---|
| Megőrzés rekompozíciókor | Igen | Igen |
| Megőrzés elforgatáskor | Nem | Igen |
| Megőrzés folyamatleállításkor | Nem | Igen |
| Típuskövetelmények | Bármilyen | Parcelable, Serializable, Saver |
| Teljesítmény | Magas | Közepes |
Vizsgáljunk meg egy tipikus forgatókönyvet — a profil szerkesztési képernyőt, ahol a remember-t több célra használjuk: az űrlapmezők állapotának tárolására, származtatott értékek kiszámítására és számításigényes műveletek gyorsítótárazására.
data class ProfileUiState(
val name: String = "",
val bio: String = "",
val isSaving: Boolean = false
)
@Composable
fun ProfileEditor() {
var state by rememberSaveable { mutableStateOf(ProfileUiState()) }
val isValid = remember {
derivedStateOf { state.name.isNotBlank() && state.bio.length() <= 500 }
}
val bioWarning = remember(state.bio) {
if (state.bio.length() > 400) {
"${500 - state.bio.length} chars left"
} else null
}
Column(modifier = Modifier.padding(16.dp)) {
OutlinedTextField(
value = state.name,
onValueChange = { state = state.copy(name = it) },
label = { Text("Név") }
)
OutlinedTextField(
value = state.bio,
onValueChange = { state = state.copy(bio = it) },
label = { Text("Rólunk") }
)
bioWarning?.let { Text(it, color = MaterialTheme.colorScheme.error) }
Button(onClick = { /* save */ },
enabled = isValid.value) {
Text("Mentés")
}
}
}
A példában az állapot rememberSaveable-en keresztül kerül mentésre — képernyőelforgatáskor a szöveg nem vész el. Az isValid a derivedStateOf segítségével kerül kiszámításra, ami megakadályozza a szükségtelen számításokat a rekompozíciók során. A bioWarning a remember-t használja a bio kulccsal — ez egy költséges számítás (opcionális, demonstrációs célból), amely csak a bio változásakor számolódik újra, nem minden rekompozíciókor.
A származtatott állapotok (derived state) olyan értékek, amelyeket más State objektumokból számítanak ki. Ahelyett, hogy minden rekompozíciókor kiszámítaná őket és CPU-t pazarolna azonos eredményekre, a remember a derivedStateOf-val csak akkor számítja ki az értéket, ha a források megváltoznak. Ez különösen hasznos az adatok szűréséhez, rendezéséhez és összesítéséhez.
remember kulcsokkal (remember(key) { calculation }) — egy másik optimalizációs mechanizmus. Ha a kulcs nem változott az előző rekompozíció óta, a számítási blokk nem hajtódik végre, és a gyorsítótárazott érték kerül visszaadásra. Ez kényelmes azon objektumok gyorsítótárazásához, amelyek létrehozása költséges: dátumformázás, JSON elemzés, nagy megváltoztathatatlan gyűjtemények létrehozása.
@Composable
fun SearchResults(allItems: List<Item>, query: String) {
// derivedStateOf: a szűrő csak a bemenetek változásakor számolódik újra
val filtered = remember {
derivedStateOf {
allItems.filter { it.title.contains(query, true) }
}
}
// remember kulccsal: a formázott statisztikák csak a lekérdezés változásakor számolódnak újra
val statsText = remember(query) {
"Results for query \"$query\": ${filtered.value.size}"
}
Text(statsText)
LazyColumn {
items(filtered.value, key = { it.id }) { item ->
Text(item.title)
}
}
}
A filtered — egy derivedStateOf, amely automatikusan újraszámolódik az allItems vagy a query változásakor. A statsText a remember(query) függvényt használja — a költséges sztringformázás csak a keresési lekérdezés változásakor hajtódik végre. A derivedStateOf és a remember kulcsokkal való kombinációja maximális teljesítményt nyújt: a származtatott állapot csak szükség esetén számolódik ki, az összetett objektumok pedig a kulcs megváltozásáig gyorsítótárazva maradnak.
Gyakran ismételt kérdések
Nem, a remember — a compose.runtime csomagból származó függvény, amely CompositionContext-et igényel. Csak @Composable függvényen belül vagy más, Composable-ből meghívott függvényen belül hívható meg. Az adatok kompozíción kívüli tárolásához használja a ViewModel-t.
Kulcs nélkül a remember csak egyszer számítja ki a blokkot — az első kompozíciókor. Az összes későbbi rekompozíció a mentett értéket adja vissza. Ha az értéket az adatok változásakor újra kell számolnia, feltétlenül adja meg azokat kulcsként: remember(data) { compute(data) }.
A remember-nek nincs közvetlen visszaállítása. Az egyetlen mód, ha eltávolítja a függvényt a kompozícióból (például elrejtve egy if-feltétellel), majd újra megjeleníti. Újbóli belépéskor a remember blokk újra végrehajtódik, létrehozva egy új kezdeti értéket.
A remember a Composable függvény slotjában tárolja az állapotot, és addig él, amíg a függvény a kompozícióban van. A ViewModel addig él, amíg a képernyő lifecycle-e él. A ViewModel elforgatáskor megmarad, és üzleti logikához használatos. A remember — a lokális UI állapothoz, amely nem szükséges egy függvényen kívül.
Igen, a remember helyesen működik a @Preview Composable függvényekben, mivel a Preview teljes értékű CompositionContext-et hoz létre. Azonban a rememberSaveable előfordulhat, hogy nem működik helyesen a Preview-ban, mivel a SavedStateHandle hiányozhat az előnézeti környezetből.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is