Navigation
On Voyager, screens are just classes with a composable function as the entrypoint. To create one, you should implement the
Screen
interface and override the Content()
composable function.You can use
data class
(if you need to send params), class
(if no param is required) or even object
(useful for tabs).object HomeScreen : Screen {
@Composable
override fun Content() {
// ...
}
}
class PostListScreen : Screen {
@Composable
override fun Content() {
// ...
}
}
data class PostDetailsScreen(val postId: Long) : Screen {
@Composable
override fun Content() {
// ...
}
}
Navigator
is a composable function deeply integrated with Compose internals. It'll manage the lifecyle, back press, state restoration and even nested navigation for you.To start using it, just set the initial
Screen
.class SingleActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Navigator(HomeScreen)
}
}
}
Use the
LocalNavigator
to navigate to other screens. Take a look at the Stack API for the available operations.class PostListScreen : Screen {
@Composable
override fun Content() {
// ...
}
@Composable
private fun PostCard(post: Post) {
val navigator = LocalNavigator.currentOrThrow
Card(
modifier = Modifier.clickable {
navigator.push(PostDetailsScreen(post.id))
// Also works:
// navigator push PostDetailsScreen(post.id)
// navigator += PostDetailsScreen(post.id)
}
) {
// ...
}
}
}
If part of your UI is shared between screens, like the
TopAppBar
or BottomNavigation
, you can easily reuse them with Voyager.@Composable
override fun Content() {
Navigator(HomeScreen) { navigator ->
Scaffold(
topBar = { /* ... */ },
content = { CurrentScreen() },
bottomBar = { /* ... */ }
)
}
}
You should use
CurrentScreen()
instead of navigator.lastItem.Content()
, because it will save the Screen's subtree for you (see SaveableStateHolder).
Last modified 1yr ago