compose-destinations: IllegalArgumentException: navigation destination test_screen is not a direct child of this NavGraph
Hey there, I’m facing this error and I’m pretty desperate.
‘IllegalArgumentException: navigation destination test_screen is not a direct child of this NavGraph’
I’m using latest version of compose-destinations - 1.9.40-beta
. I have a multi-module project with more graphs. I copy-pasted the code from tivi project with small modifications (mentioned in 1.9.40-beta release notes).
I added to all my modules build.gradle.kts
files this block of code:
ksp {
arg("compose-destinations.moduleName", "test")
arg("compose-destinations.mode", "destinations")
arg("compose-destinations.generateNavGraphs", "false")
}
Also here is my Destination
s (only with Text, for simplicity)
@Destination
@Composable
fun TestScreen(){
Column(){
Text("Test")
}
}
@Destination
@Composable
fun TestOneScreen(){
Column(){
Text("Test 1")
}
}
and here is Navigation code:
object NavGraphs {
val test = object : NavGraphSpec {
override val destinationsByRoute = emptyMap<String, DestinationSpec<*>>()
override val route = "test"
override val startRoute = TestScreenDestination routedIn this
}
val test1 = object : NavGraphSpec {
override val destinationsByRoute = emptyMap<String, DestinationSpec<*>>()
override val route = "test1"
override val startRoute = TestOneScreenDestination routedIn this
}
val root = object : NavGraphSpec {
override val route = "root"
override val startRoute = test
override val destinationsByRoute = emptyMap<String, DestinationSpec<*>>()
override val nestedNavGraphs = listOf(
test, test1
)
}
}
fun ArrayDeque<NavBackStackEntry>.print(prefix: String = "stack") {
val stack = toMutableList()
.map { it.destination.route }
.toTypedArray().contentToString()
println("$prefix = $stack")
}
fun DependenciesContainerBuilder<*>.currentNavigator(): CommonNavGraphNavigator {
return CommonNavGraphNavigator(
navBackStackEntry.destination.navGraph(),
navController
)
}
@OptIn(ExperimentalMaterialNavigationApi::class)
@ExperimentalAnimationApi
@Composable
internal fun AppNavigation(
navController: NavHostController,
modifier: Modifier = Modifier,
) {
DestinationsNavHost(
engine = rememberAnimatedNavHostEngine(
rootDefaultAnimations = RootNavGraphDefaultAnimations(
enterTransition = { defaultEnterTransition(initialState, targetState) },
exitTransition = { defaultExitTransition(initialState, targetState) },
popEnterTransition = { defaultPopEnterTransition() },
popExitTransition = { defaultPopExitTransition() },
)
),
navController = navController,
navGraph = NavGraphs.root,
modifier = modifier,
dependenciesContainerBuilder = {
dependency(currentNavigator())
}
)
}
@ExperimentalAnimationApi
private fun AnimatedContentTransitionScope<*>.defaultEnterTransition(
initial: NavBackStackEntry,
target: NavBackStackEntry,
): EnterTransition {
val initialNavGraph = initial.destination.hostNavGraph
val targetNavGraph = target.destination.hostNavGraph
// If we're crossing nav graphs (bottom navigation graphs), we crossfade
if (initialNavGraph.id != targetNavGraph.id) {
return fadeIn()
}
// Otherwise we're in the same nav graph, we can imply a direction
return fadeIn() + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start)
}
@ExperimentalAnimationApi
private fun AnimatedContentTransitionScope<*>.defaultExitTransition(
initial: NavBackStackEntry,
target: NavBackStackEntry,
): ExitTransition {
val initialNavGraph = initial.destination.hostNavGraph
val targetNavGraph = target.destination.hostNavGraph
// If we're crossing nav graphs (bottom navigation graphs), we crossfade
if (initialNavGraph.id != targetNavGraph.id) {
return fadeOut()
}
// Otherwise we're in the same nav graph, we can imply a direction
return fadeOut() + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start)
}
private val NavDestination.hostNavGraph: NavGraph
get() = hierarchy.first { it is NavGraph } as NavGraph
@ExperimentalAnimationApi
private fun AnimatedContentTransitionScope<*>.defaultPopEnterTransition(): EnterTransition {
return fadeIn() + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.End)
}
@ExperimentalAnimationApi
private fun AnimatedContentTransitionScope<*>.defaultPopExitTransition(): ExitTransition {
return fadeOut() + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.End)
}
Tried to remove routedIn (but it was not working). Try all advices what I see in issues in repos, but still not working.
Do you have any idea what I’m doing wrong? Thanks
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15 (9 by maintainers)
Like this it works. Reason is that routedIn call actually calls route, but if route is only initialized after, then it returns null. So the final route is
null/test
.Expect the multi module experience to improve soon. But right now this is the case…
Turns out you need to specify route before calling routedIn 🤦
Sure, here it is: https://github.com/Vlado24/compose-destinations-example same error. Tried with different startRoute, but still not working.