Ballast Navigation Extension
September 28, 2023 · View on GitHub
An opinionated fast Ballast Navigation set-up for Compose multiplatform (Android & iOS for now)
Set up
Add dependency
Android:
implementation("com.dilivva.ballastnavigationext:ballastnavigationext:LATEST")
Multiplatform: Android & iOS
val commonMain by getting {
dependencies {
//put your multiplatform dependencies here
api("com.dilivva.ballastnavigationext:ballastnavigationext:LATEST")
}
}
Define your Screens/Routes
Extend the BaseRoute interface:
enum class MainRoute(
override val route: String
): BaseRoute{
Home("/home"),
SignIn("/sign-in"),
SignUp("/sign-up"),
ForgotPassword("/forgot-password"),
Dashboard("/dashboard?email={?}"),
Profile("/profile");
}
More on Ballast Route Matching
Create your Navigator Object
@Composable
fun MainNavigation() {
val applicationScope = rememberCoroutineScope()
val navigator = rememberNavigator(applicationScope, MainRoute.values())
}
The rememberNavigator assumes your first defined route in your
enum class in the initial route. You can override that by passing in
a callback that will return your desired initial route:
@Composable
fun MainNavigation() {
var isLoggedIn by remember { mutableStateOf(false) }
val applicationScope = rememberCoroutineScope()
val navigator = rememberNavigator(applicationScope, MainRoute.values()) {
if (isLoggedIn) MainRoute.Dashboard else MainRoute.Home
}
}
Handle route changes
Destination(
navigator = navigator,
onNavigate = {
when (it) {
//Handle changes here...
}
}
)
Navigate!
Navigate to a screen:
navigator.navigate(MainRoute.SignIn)
Navigate back
navigator.navigateUp()
Navigate to a screen popping up backstack to a particular screen:
navigator.navigateWithPop(destination = MainRoute.Profile, popUpTo = MainRoute.Home)
Navigate to a screen after popping the backstack:
navigator.navigateWithPopAll(destination = MainRoute.Profile)
Passing data
Ballast Navigation supports passing data between destinations using query or path parameters. Read more
To pass data, just override the extras callback of any of the
navigate** function:
navigator.navigate(MainRoute.Profile){
pathParameter("user","john").queryParameter("email","john@gmail.com")
}
EXTRAS
Device Back press (Android):
The library automatically handles device back pressed, if you want
to override that, pass in a value for onDeviceBackPressed:
Destination(
//..//
onDeviceBackPressed = {
if (it == MainRoute.Dashboard){
//close app
}else{
navigator.navigateUp()
}
}
)
Transitions:
There's a default enter and exit animations (Slide in/out), but you can
override that and pass in your own enter and exit animations to the
animateIn and animateOut callbacks:
Destination(
//..//
animateIn = { },
animateOut = { }
)
If a route cannot be matched noDestination callback will be invoked
the library automatically does nothing, you can override that.
DeepLinking
Deep links are supported automatically with few extra setups
Android:
Define your scheme in the android Manifest:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "ballast://dashboard” -->
<data android:scheme="ballast"
android:host="app" />
</intent-filter>
That's all!
Test your deep link:
adb shell am start -W -a android.intent.action.VIEW -d "ballast://app/dashboard?email=dilivva@email.com"
The above command deep links to the dashboard screen passing in an email
address. So when deep linking to a screen in your app the pattern
is as follows
scheme://host/screen.
iOS
Define your URL scheme:

Lastly let the library handle the linking:
ContentView().onOpenURL { link in
//Set up to support URL scheme
DeepLinkResult.companion.setUrl(url: link.absoluteString)
}
That's all!!
Example screens
Android:
https://github.com/Dilivva/BallastNavigationExt/assets/61739400/67104fcf-8194-4b40-a6d0-7c249611fd47
iOS:
https://github.com/Dilivva/BallastNavigationExt/assets/61739400/4e5e05e5-a1ab-4768-9c07-33028916777a
Acknowledgements
Ballast: for the awesome routing/navigation library
License
BallastNavigationExt is licensed under the MIT License, see LICENSE.md.