Skip to content

πŸ—ΊοΈ Cartographer is a lightweight but powerful Jetpack Compose library designed to simplify navigation and allow for object passing between screens

License

Notifications You must be signed in to change notification settings

erictoader/Cartographer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


πŸ—ΊοΈ Compose Cartographer

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.

🌟 Features

  • 🌐 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.

πŸ”§ Installation

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")
    }

πŸš€ How to Use

1. Define Your Destinations πŸ“

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()

2. Define your NavGraph 🌏

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
        }
    }
}

3. Navigate with Ease πŸš€

Navigate to new screens and pass arguments with ease:

navController.navigate(
    Main.Details(
        primaryAsset = Asset(.. some complex data),
        secondaryAsset = Asset(.. some more complex data)
    )
)

4. Retrieve Arguments 🎣

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")

πŸ› οΈ Configuration

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
        }
    }
}

πŸ“– More information

The rest of the features, public API as well as the inner workings of Cartographer are detailed in the Wiki pages.

πŸ“ License

This project is licensed under the MIT License.

πŸ€” Queries?

Got questions or suggestions? Don't hesitate to open an issue on this repository!

About

πŸ—ΊοΈ Cartographer is a lightweight but powerful Jetpack Compose library designed to simplify navigation and allow for object passing between screens

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages