如何在Jetpack Compose中使用类型安全导航检查当前路由是否属于父接口?
问题:检查当前路由是否属于Routes.TopLevel的派生类
我的路由定义如下:
@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 }
我想要检查当前路由是否为Routes.TopLevel类型,但尝试的代码仅能检查路由是否是Routes.TopLevel本身,无法识别它的派生类(比如Home、Journal这些实现类):
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>() }
解决方案
问题出在hasRoute<T>()是精确匹配类型,只会返回true当路由完全等于T本身,而不会识别T的子类/实现类。我们需要修改逻辑,改为检查当前路由实例是否属于T的类型(包括子类)。
修改后的扩展函数
// NavDestinationExt.kt inline fun <reified T : Routes> NavDestination.isRouteOrSubtype(): Boolean = hierarchy.any { entry -> // 从导航参数中获取当前路由实例(根据你的路由传递方式调整) entry.arguments?.getSerializable("route")?.let { it as? Routes is T } ?: false }
使用方式
val navHostController = rememberNavController() val currentBackStackEntry by navHostController.currentBackStackEntryAsState() val currentDestination = currentBackStackEntry?.destination val isTopLevelRoute = currentDestination?.isRouteOrSubtype<Routes.TopLevel>() == true
更直接的简化方式
如果能直接获取当前路由实例,也可以跳过扩展函数直接判断:
val currentRoute = currentBackStackEntry?.arguments?.getSerializable("route") as? Routes val isTopLevelRoute = currentRoute is Routes.TopLevel
以上两种方式都能正确识别所有Routes.TopLevel的派生类,比如Home、Journal等。
内容的提问来源于stack exchange,提问作者mainrs
相关产品推荐
相关产品推荐

