State restoration
The Screen interface is Serializable. Every param of your screens will be saved and restored automatically. Because of that, it's important to know what can be passed as param: anything that can be stored inside a Bundle.
1
// ✔️ DO
2
@Parcelize
3
data class Post(/*...*/) : Parcelable
4
5
data class ValidScreen(
6
val userId: UUID, // Built-in serializable types
7
val post: Post // Your own parcelable and serializable types
8
) : Screen {
9
// ...
10
}
11
12
// 🚫 DON'T
13
class Post(/*...*/)
14
15
data class InvalidScreen(
16
val context: Context, // Built-in non-serializable types
17
val post: Post // Your own non-parcelable and non-serializable types
18
) : Screen {
19
// ...
20
}
Copied!
Not only the params, but the properties will also be restored, so the same rule applies.
1
// ✔️ DO
2
class ValidScreen : Screen {
3
4
// Serializable properties
5
val tag = "ValidScreen"
6
7
// Lazily initialized serializable types
8
val randomId by lazy { UUID.randomUUID() }
9
10
// Lambdas
11
val callback = { /*...*/ }
12
}
13
14
// 🚫 DON'T
15
class InvalidScreen : Screen {
16
17
// Non-serializable properties
18
val postService = PostService()
19
}
Copied!
If you want to inject dependencies through a DI framework, make sure it supports Compose, like Koin and Kodein.
1
// ✔️ DO
2
class ValidScreen : Screen {
3
4
@Composable
5
override fun Content() {
6
// Inject your dependencies inside composables
7
val postService = get<PostService>()
8
}
9
}
10
11
// 🚫 DON'T
12
class InvalidScreen : Screen {
13
14
// Using DI to inject non-serializable types as properties
15
val postService by inject<PostService>()
16
}
Copied!

Identifying screens

The Screen interface has a key property used for saving and restoring the states for the subtree. You can override the default value to set your own key.
1
class HomeScreen : Screen {
2
3
override val key = "CUSTOM_KEY"
4
5
@Composable
6
override fun Content() {
7
// ...
8
}
9
}
Copied!
Voyager provides a uniqueScreenKey property, useful if you don't want to manage the keys yourself.
1
override val key = uniqueScreenKey
Copied!
You should always set your own key if the screen:
  • Is used multiple times in the same Navigator
  • Is an anonymous or local class
Last modified 3mo ago
Copy link