Compose Cartographer is a robust Jetpack Compose library, specifically designed to compliment the official Compose navigation by taking the complexity out of navigation within your Android applications.
It brings simplicity to the forefront, allowing developers to navigate through screens while passing any type of objects with an unparalleled level of ease.
Cartographer utilizes Serialization and Reflection to pass objects and simplify developer experience to the maximum.
- π Seamless Navigation: Navigate between screens using Destinations, not routes.
- π¦ Type-Safe Argument Passing: Use arguments without the hassle. Pass objects between screens with ease.
- π¨ Enhanced NavGraph: Declare your simple/nested NavGraph using Destination classes.
- π Customization: Provide your own JsonAdapters for complex objects.
Integrating Compose Cartographer into your project is a breeze. Just add the following line to your module build.gradle
file:
dependencies {
implementation 'com.github.erictoader:Cartographer:1.0.0'
}
Note: You will need to add Jitpack to your project repositories. To do so, add the following line to your top-level build.gradle
file:
repositories {
// other repositories
maven("https://jitpack.io")
}
Declare your destinations as classes that inherit from the Destination
class:
In this example, we are creating a nested navigation of the Authentication feaure.
object Auth : Destination() {
object Splash : Destination()
object Login : Destination()
}
For destinations that require arguments, use data classes.
data class Player(
val asset: Asset
) : Destination()
For destinations which require more than one instance of an argument type, use @NamedArgument
annotation.
This makes it easy to refer to them separately in code, and ensures everything works, even when renaming properties.
data class Details(
@NamedArgument("primary") val primaryAsset: Asset,
@NamedArgument("secondary") val secondaryAsset: Asset
) : Destination()
This is a nested NavGraph. Your NavGraph can be as simple or as complicated as you like.
NavHost(
navController = navController,
startDestination = Main::class
) {
navigation(
routeClass = Auth::class,
startDestinationClass = Auth.Splash::class
) {
composable(Auth.Splash::class) {
// some composable
}
composable(Auth.Login::class) {
// some other composable
}
}
navigation(
routeClass = Main::class,
startDestinationClass = Main.Home::class
) {
composable(Main.Home::class) {
// some composable
}
composable(Main.Player::class) { backStackEntry ->
// some other composable
}
}
}
Navigate to new screens and pass arguments with ease:
navController.navigate(
Main.Details(
primaryAsset = Asset(.. some complex data),
secondaryAsset = Asset(.. some more complex data)
)
)
Retrieve arguments with type-safety, null-safety and name-safety:
composable(Main.Player::class) { backStackEntry ->
val asset = backStackEntry.getArg<Asset>() // non-null asserted, perfect for Fail-Fast approach
val maybeAsset = backStackEntry.getArgNullable<Asset>() // null-safe
PlayerScreen(
asset = asset
)
}
Or, when using multiple arguments of the same type, refer them by their defined name:
val asset1 = backStackEntry.getArg<Asset>(named = "primary")
val asset2 = backStackEntry.getArg<Asset>(named = "secondary")
To handle complex object serialization, provide custom JsonAdapters using CartographerConfig
.
This should be done before navigating to any destination.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CartographerConfig.apply {
addJsonAdapterFactory(.. some Adapter factory)
addJsonAdapter(.. some Json adapter)
)
setContent {
// composable
}
}
}
The rest of the features, public API as well as the inner workings of Cartographer are detailed in the Wiki pages.
This project is licensed under the MIT License.
Got questions or suggestions? Don't hesitate to open an issue on this repository!