Keep Compose UI State Across Rotations with rememberSaveable
Use rememberSaveable to keep Compose UI state—text, toggles, lists—through device rotations without a ViewModel. Follow the step‑by‑step guide, verify with Layout Inspector, and know the limits.
05 Oct 2026, 09:07 UTC

Problem: UI state vanishes on rotation
When a device rotates, Android destroys and recreates the activity. If a composable stores state only with mutableStateOf, the value is lost unless the state is hoisted and preserved.
Desired Outcome
Preserve simple UI‑only data—text input, toggle status, list items—through configuration changes without writing a ViewModel.
Prerequisites
- Android Studio Arctic Fox (2020.3.1) or newer
- Compose BOM 2023.10.00 (or later) in your Gradle dependencies
- Project uses Kotlin 1.8+
- A minimal activity that calls
setContent { }and contains at least one composable that displays state.
Procedure
- Hoist the state with
rememberSaveableso Compose can write it to the activity’sBundleduring configuration changes.
@Composable
fun NameInput() {
var name by rememberSaveable { mutableStateOf("") }
TextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") }
)
}
When the composable is called from a parent, hoist the state one level higher and expose a callback to update it.
@Composable
fun NameInputScreen() {
var name by rememberSaveable { mutableStateOf("") }
NameInput(value = name, onValueChange = { name = it })
}
@Composable
fun NameInput(value: String, onValueChange: (String) -> Unit) {
TextField(value = value, onValueChange = onValueChange, label = { Text("Name") })
}
- Handle complex types with a
Saveror a built‑in saver such aslistSaver.
Example: a mutable list of strings that should keep its scroll position.
val items by rememberSaveable(
saver = listSaver(
save = { it },
restore = { it }
)
) { mutableListOf() }
LazyColumn {
items(items) { item -> Text(item) }
}
For a custom data class, implement a Saver that converts the object to a Bundle-friendly representation.
data class User(val id: Int, val name: String)
object UserSaver : Saver> {
override fun save(value: User): Pair = value.id to value.name
override fun restore(value: Pair): User = User(value.first, value.second)
}
val user by rememberSaveable(saver = UserSaver) { mutableStateOf(User(0, "")) }
Expected Checks
- Run the app on an emulator or a physical device.
- Enter text into a
TextFieldor add items to a list. - Rotate the device (or trigger a configuration change via
adb shell am broadcast -a android.intent.action.CONFIGURATION_CHANGED). - Verify that the UI still shows the entered text, selected toggle, or list items exactly as before.
Diagnostics
- Open
View > Tool Windows > Layout Inspectorin Android Studio. - Navigate to the composable tree and locate the node created by
rememberSaveable. - Compare the
valuebefore and after rotation; it should be unchanged.
Limitations & Recovery Options
- Supported types:
rememberSaveableworks only for primitives,String,Parcelable, and types that have aSaver. Non‑parcelable custom classes need a customSaveror should be moved to aViewModelwithSavedStateHandle. - Process death:
rememberSaveablesurvives configuration changes but not a low‑memory kill. For data that must survive process death, use aViewModelbacked bySavedStateHandleor persistent storage. - Key stability: When hoisting state inside a list or a composable that can be recreated, provide a stable key to
rememberSaveable(key = "uniqueKey")so Compose can match the instance across recompositions. - Over‑hoisting: Hoisting state higher than necessary creates extra recompositions. Keep the state as close as possible to the composables that actually read it.
Practical Verification
After rotation, inspect the saved instance state bundle with:
adb shell dumpsys activity activities | grep mSavedInstanceState
Look for the key that Compose uses (e.g., androidx.compose.runtime.saveable.StateHolder). The presence of your data indicates that rememberSaveable wrote it successfully.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.