remember — je funkce v Jetpack Compose, která umožňuje uchovávat hodnotu mezi rekompozicemi, čímž zabraňuje resetování stavu při každém restartu Composable funkce. Bez remember by všechny proměnné deklarované uvnitř funkce byly při každé aktualizaci UI vynulovány, což by stav činilo nestabilním a nepoužitelným. Podle Google Android Developers, 2026 je správné použití remember základem korektní správy stavu v deklarativním UI.
Hlavní body
remember — je vestavěná funkce Jetpack Compose z balíčku androidx.compose.runtime, která vytváří objekt uchovávající svou hodnotu mezi po sobě jdoucími voláními Composable funkce. Technicky remember pracuje se sloty — speciálními paměťovými buňkami přidělenými pro každou pozici volání funkce ve stromu UI. Dokud funkce zůstává v kompozici (není odstraněna pomocí podmínky if), remember bude při každé rekompozici vracet uloženou hodnotu.
Syntaxe remember je jednoduchá: ve složených závorkách je uveden blok výpočtu počáteční hodnoty. Blok se provede pouze jednou — při první kompozici funkce. Všechny následující rekompozice vracejí již uloženou hodnotu, aniž by blok znovu volaly. Pokud je však uveden klíč (parametr key), blok se znovu provede při změně klíče, což umožňuje přepočítat hodnotu na základě vstupních dat.
remember není kouzlo Kotlinu — je to jednoduchá funkce s parametrem key a výpočetní lambdou. Její vnitřní implementace používá Composer pro čtení a zápis do slotů. Kotlin kompilátor při spatření volání remember generuje kód, který přistupuje k aktuálnímu CompositionContext a spravuje sloty. To znamená, že remember lze volat pouze uvnitř Composable funkce nebo jiné funkce v kontextu kompozice.
V Jetpack Compose existují tři hlavní varianty remember, každá se svým vlastním účelem. Základní remember uchovává hodnotu pouze v paměti aktuálního procesu — při otočení obrazovky (config change) Compose znovu vytvoří Composition a všechny remember hodnoty se resetují. Pro uchování dat při změnách konfigurace a zastavení procesu se používá rememberSaveable.
rememberSaveable serializuje hodnotu do Bundle prostřednictvím mechanismu SavedStateHandle nebo Parcelable. To umožňuje přežít otočení obrazovky, volání „Neuchovávat aktivity“ a dokonce i dočasné minimalizování aplikace. Nicméně rememberSaveable ukládá omezení na typ uchovávaných dat: musí to být primitivy, Parcelable, Serializable nebo musí podporovat konvertor Saver.
derivedStateOf — není mechanismus uchovávání, ale optimalizace. Vytváří State, jehož hodnota se vypočítává na základě jiných objektů State. derivedStateOf reaguje na změny zdrojových stavů, ale přepočítává hodnotu pouze v přítomnosti odběratelů. Pokud aktuální rekompozice nečte derivedStateOf, výpočet se neprovede, což šetří zdroje při častých, ale nikým nevyžadovaných aktualizacích.
@Composable
fun RememberVariants() {
// 1. Základní remember: trvá do opuštění kompozice
val createdAt = remember { System.currentTimeMillis() }
// 2. rememberSaveable: přežije otočení obrazovky
var username by rememberSaveable { mutableStateOf("") }
// 3. derivedStateOf: vypočítáno pouze když je potřeba
val isButtonVisible = remember {
derivedStateOf { username.length() > 3 }
}
Text("Vytvořeno: $createdAt")
TextField(value = username, onValueChange = { username = it })
if (isButtonVisible.value) {
Text("Tlačítko bude zobrazeno")
}
}
Volba mezi remember a rememberSaveable závisí na tom, jak kritické je uchování dat při změnách konfigurace. Pro dočasné stavy, jejichž ztráta při otočení není důležitá (animace, aktuální pozice posouvání, stav fokusu) — stačí obyčejné remember. Pro kritická data (text ve formuláři, vybrané položky, zaškrtávací políčka) — použijte rememberSaveable.
Výkon rememberSaveable je nižší než u obyčejného remember, protože vyžaduje serializaci do Bundle. Používejte rememberSaveable pouze pro data, která skutečně musí přežít znovuvytvoření Activity. Pro všechno ostatní — obyčejné remember. Nadměrné používání rememberSaveable vede ke zpomalení při otáčení obrazovky a přepínání mezi aplikacemi.
Pokud pracujete s třídami, které nepodporují Parcelable nebo Serializable, použijte Saver — konvertor, který určuje, jak uložit a obnovit objekt. Saver je popsán dvojicí lambd: save (převádí objekt na ukládající typ) a restore (obnovuje objekt z uložených dat). Standardní Saver je již implementován pro mutableStateListOf a mutableStateMapOf.
| Vlastnost | remember | rememberSaveable |
|---|---|---|
| Uchování při rekompozici | Ano | Ano |
| Uchování při otočení | Ne | Ano |
| Uchování při zastavení procesu | Ne | Ano |
| Požadavky na typ | Jakýkoli | Parcelable, Serializable, Saver |
| Výkon | Vysoký | Střední |
Podívejme se na typický scénář — obrazovku úpravy profilu, kde se remember používá pro několik účelů: ukládání stavu polí formuláře, výpočet odvozených hodnot a ukládání do mezipaměti výpočetně náročných operací.
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("Jméno") }
)
OutlinedTextField(
value = state.bio,
onValueChange = { state = state.copy(bio = it) },
label = { Text("O nás") }
)
bioWarning?.let { Text(it, color = MaterialTheme.colorScheme.error) }
Button(onClick = { /* save */ },
enabled = isValid.value) {
Text("Uložit")
}
}
}
V příkladu je stav ukládán prostřednictvím rememberSaveable — při otočení obrazovky text nezmizí. isValid se vypočítává přes derivedStateOf, což zabraňuje zbytečným výpočtům při rekompozicích. bioWarning používá remember s klíčem bio — jedná se o náročný výpočet (volitelně, pro demonstraci), který se přepočítává pouze při změně bio, ne při každé rekompozici.
Odvozené stavy (derived state) jsou hodnoty, které se vypočítávají z jiných objektů State. Místo toho, abyste je počítali při každé rekompozici a plýtvali CPU na identické výsledky, remember s derivedStateOf vypočítává hodnotu pouze při změně zdrojů. To je užitečné zejména pro filtrování, řazení a agregaci dat.
remember s klíči (remember(key) { calculation }) — další optimalizační mechanismus. Pokud se klíč nezměnil od předchozí rekompozice, výpočetní blok se neprovede a vrátí se hodnota z mezipaměti. To je vhodné pro ukládání do mezipaměti objektů, jejichž vytvoření je náročné: formátování dat, parsování JSON, vytváření velkých neměnných kolekcí.
@Composable
fun SearchResults(allItems: List<Item>, query: String) {
// derivedStateOf: filtr se přepočítává pouze při změně vstupů
val filtered = remember {
derivedStateOf {
allItems.filter { it.title.contains(query, true) }
}
}
// remember s klíčem: formátované statistiky se přepočítávají pouze při změně dotazu
val statsText = remember(query) {
"Results for query \"$query\": ${filtered.value.size}"
}
Text(statsText)
LazyColumn {
items(filtered.value, key = { it.id }) { item ->
Text(item.title)
}
}
}
filtered — je derivedStateOf, který se automaticky přepočítává při změně allItems nebo query. statsText používá remember(query) — náročné formátování řetězce se provádí pouze při změně vyhledávacího dotazu. Kombinace derivedStateOf a remember s klíči poskytuje maximální výkon: odvozený stav se počítá pouze když je potřeba, a složité objekty jsou ukládány do mezipaměti až do změny klíče.
Často kladené otázky
Ne, remember — je funkce z balíčku compose.runtime, která vyžaduje CompositionContext. Může být volána pouze uvnitř @Composable funkce nebo uvnitř jiné funkce volané z Composable. Pro ukládání dat mimo kompozici použijte ViewModel.
Bez klíče remember vypočítá blok pouze jednou — při první kompozici. Všechny následující rekompozice vracejí uloženou hodnotu. Pokud potřebujete přepočítávat hodnotu při změně dat, nezapomeňte je uvést jako klíč: remember(data) { compute(data) }.
Neexistuje přímý reset remember. Jediným způsobem je odebrat funkci z kompozice (například skrytím pomocí podmínky if) a poté ji znovu zobrazit. Při opětovném vstupu se blok remember znovu provede a vytvoří novou počáteční hodnotu.
remember ukládá stav do slotu Composable funkce a žije, dokud je funkce v kompozici. ViewModel žije, dokud žije lifecycle obrazovky. ViewModel je zachován při otočení a používá se pro obchodní logiku. remember — pro lokální UI stav, který není potřeba mimo jednu funkci.
Ano, remember funguje správně v @Preview Composable funkcích, protože Preview vytváří plnohodnotný CompositionContext. Nicméně rememberSaveable nemusí v Preview fungovat správně, protože SavedStateHandle může v prostředí náhledu chybět.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také