admin 管理员组

文章数量: 1087132

My routes are defined like this:

@Serializable
sealed interface Routes {

    @Serializable
    sealed interface TopLevel: Routes {
        @Serializable
        data object Home : TopLevel
        @Serializable
        data object Journal : TopLevel
        @Serializable
        data object Meals : TopLevel
        @Serializable
        data object Workouts : TopLevel
        @Serializable
        data object Profile : TopLevel
    }

    @Serializable
    data object Onboarding : Routes
    @Serializable
    data object Settings : Routes
}

I want to check if my current route is of type Routes.TopLevel. I tried this, but my understanding is that it checks if the Route is Routes.TopLevel and not one of its derivatives.

val navHostController = rememberNavController()
val currentBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination = currentBackStackEntry?.destination

val isTopLevelRoute = currentDestination?.isRoute<Routes.TopLevel>() == true

// NavDestinationExt.kt
inline fun <reified T : Routes> NavDestination.isRoute(): Boolean =
    this.hierarchy.any { it.hasRoute<T>() }

My routes are defined like this:

@Serializable
sealed interface Routes {

    @Serializable
    sealed interface TopLevel: Routes {
        @Serializable
        data object Home : TopLevel
        @Serializable
        data object Journal : TopLevel
        @Serializable
        data object Meals : TopLevel
        @Serializable
        data object Workouts : TopLevel
        @Serializable
        data object Profile : TopLevel
    }

    @Serializable
    data object Onboarding : Routes
    @Serializable
    data object Settings : Routes
}

I want to check if my current route is of type Routes.TopLevel. I tried this, but my understanding is that it checks if the Route is Routes.TopLevel and not one of its derivatives.

val navHostController = rememberNavController()
val currentBackStackEntry by navHostController.currentBackStackEntryAsState()
val currentDestination = currentBackStackEntry?.destination

val isTopLevelRoute = currentDestination?.isRoute<Routes.TopLevel>() == true

// NavDestinationExt.kt
inline fun <reified T : Routes> NavDestination.isRoute(): Boolean =
    this.hierarchy.any { it.hasRoute<T>() }
Share Improve this question asked Mar 28 at 16:34 mainrsmainrs 631 silver badge5 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

What you need is not possible in jetpack compose navigation.

The library doesn't store the type of passed object or class as a route.
Here is the code from Jetpack compose library:

public fun <T : Any> navigate(
        route: T,
        navOptions: NavOptions? = null,
        navigatorExtras: Navigator.Extras? = null
    ) {
        val finalRoute : String = generateRouteFilled(route)
        navigate(
            NavDeepLinkRequest.Builder.fromUri(createRoute(finalRoute).toUri()).build(),
            navOptions,
            navigatorExtras
        )
    }

the route passed as a parameter is converted to a String using generateRouteFilled function. and never used afterward.
On the other hand, when building the navgraph, only a navigator, id, and route (string) are stored.

public open class NavDestinationBuilder<out D : NavDestination>
internal constructor(
    protected val navigator: Navigator<out D>,
    @IdRes public val id: Int,
    public val route: String?
)

That ID is used to determine whether or not a route is generated using a type by getting hashcode of it's serializer. So it's impossible to retrieve the actual type.

A similar solution:

If your inner destinations (in your case, TopLevel) represents a nested graph, you can nest them inside a graph and check that the graph is in the current backstack.

本文标签:

Error[2]: Invalid argument supplied for foreach(), File: /www/wwwroot/roclinux.cn/tmp/view_template_quzhiwa_htm_read.htm, Line: 58
File: /www/wwwroot/roclinux.cn/tmp/route_read.php, Line: 205, include(/www/wwwroot/roclinux.cn/tmp/view_template_quzhiwa_htm_read.htm)
File: /www/wwwroot/roclinux.cn/tmp/index.inc.php, Line: 129, include(/www/wwwroot/roclinux.cn/tmp/route_read.php)
File: /www/wwwroot/roclinux.cn/index.php, Line: 29, include(/www/wwwroot/roclinux.cn/tmp/index.inc.php)