Multi-module navigation
Voyager has built-in support for multi-module navigation. Its API is based on great DI frameworks like Koin and Kodein, so should be familiar to use.
Suppose we have the following modules:
  • app: the entrypoint of our app, contains the Activity
  • feature-home: contains the root screen (HomeScreen)
  • feature-posts: contains screens related to the posts feature (ListScreen and DetailsScreen)
  • navigation: contains the screen providers used to navigate between modules, both feature-home and feature-posts imports it
To navigate from HomeScreen to the screens on feature-posts module (ListScreen and DetailsScreen), we first need to provide them. The navigation module should declare all shared screens in the app, use the ScreenProvider interface for that.
navigation/../SharedScreen.kt
1
sealed class SharedScreen : ScreenProvider {
2
object PostList : SharedScreen()
3
data class PostDetails(val id: String) : SharedScreen()
4
}
Copied!
Now use the ScreenRegistry to register these providers. This should be done in yourApplication class.
app/../MyApp.kt
1
class MyApp : Application() {
2
3
override fun onCreate() {
4
super.onCreate()
5
6
ScreenRegistry {
7
register<SharedScreen.PostList> {
8
ListScreen()
9
}
10
register<SharedScreen.PostDetails> { provider ->
11
DetailsScreen(id = provider.id)
12
}
13
}
14
}
15
}
Copied!
You can also create a screenModule into your feature module, that way your Application class won't be bloated by too many declarations.
ScreenModule
feature-posts/../ScreenModule.kt
1
val featurePostsScreenModule = screenModule {
2
register<SharedScreen.PostList> {
3
ListScreen()
4
}
5
register<SharedScreen.PostDetails> { provider ->
6
DetailsScreen(id = provider.id)
7
}
8
}
Copied!
app/../MyApp.kt
1
override fun onCreate() {
2
super.onCreate()
3
4
ScreenRegistry {
5
featurePostsScreenModule()
6
}
7
}
Copied!
Finally, call rememberScreen() (inside a composable function) or ScreenRegistry.get() to access your screens.
feature-home/../HomeScreen.kt
1
class HomeScreen : Screen {
2
3
@Composable
4
override fun Content() {
5
val navigator = LocalNavigator.currentOrThrow
6
val postListScreen = rememberScreen(SharedScreen.PostList)
7
val postDetailsScreen = rememberScreen(SharedScreen.PostDetails(id = postId))
8
9
// navigator.push(postListScreen)
10
// navigator.push(postDetailsScreen)
11
}
12
}
Copied!

Sample

Source code here.
Last modified 3mo ago
Copy link
Contents
Sample