compose-destinations is my recommended library.
Generate helper methods for compose navigation using KSP.
- Support argument types.
- Support animation navigation.
- Refactor continuously
Add @NavGen
annotation to each compose screen.
@NavGen("list")
@Composable
fun ListScreen(navController: NavController) {
// ...
}
@NavGen("detail")
@Composable
fun DetailScreen(data: String, navController: NavController) {
// ...
}
When build, the processor generates helper methods from @NavGen
.
Generated code
// list
fun NavGraphBuilder.list(navController: NavController) {
composable("list") {
ListScreen(navController)
}
}
public fun NavController.list(): Unit {
navigate("list")
}
// detail
fun NavGraphBuilder.detail(navController: NavController) {
composable(
"detail/{data}",
arguments = listOf(navArgument("data") { type = NavType.StringType })
) { backStackEntry ->
DetailScreen(
backStackEntry.arguments!!.getString("data")!!,
navController,
)
}
}
fun NavController.detail(`data`: String) {
navigate("detail/$data")
}
You can use generated code for compose navigation.
val navController = rememberNavController()
NavHost(navController = navController, startDestination = NavGenRoutes.list) {
list(navController) // Add route 'list'
detail(navController) // Add route 'detail/{data}'
}
// navigate to next screen
navController.detail(data) // Call NavController.navigate("detail/$data")
If you want to use optional arguments, you can use nullable or a default value.
@NavGen("sample")
@Composable
fun SampleScreen(
data1: String?,
@DefaultString("default") data2: String
) {
// ...
}
Generated code
composable("sample?data1={data1}&data2={data2}",
arguments = listOf(
navArgument("data1") { type = NavType.StringType; nullable = true },
navArgument("data2") { type = NavType.StringType; defaultValue = "default" },
)
) { backStackEntry ->
// ...
}
If you use nullable or a optional value, no need pass a arguemnt.
navController.sample()
Android Studio does not automatically index generated codes by KSP. You have to add sourceSets manually.
Ref: google/ksp#37
- build.gradle.kts
android {
// ...
applicationVariants.all {
val variantName = name
sourceSets {
getByName("main") {
java.srcDir(File("build/generated/ksp/$variantName/kotlin"))
}
}
}
}
- build.gradle
android {
// ...
applicationVariants.all { variant ->
variant.sourceSets.java.each {
it.srcDirs += "build/generated/ksp/${variant.name}/kotlin"
}
}
}
plugins {
id("com.google.devtools.ksp") version "1.5.30-1.0.0"
}
dependencies {
implementation("androidx.navigation:navigation-compose:2.4.0-alpha10")
implementation("com.star-zero:compose-navgen:1.0.0-alpha02")
ksp("com.star-zero:compose-navgen-processor:1.0.0-alpha02")
}
Copyright 2021 Kenji Abe
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.