Skip to content

路由配置

介绍

路由配置的目标是让每个模块独立维护页面入口,并由应用统一挂载。核心步骤是:

  1. 定义模块路由(*Routes)。
  2. 提供模块跳转封装(*Navigator)。
  3. 在 Feature 的 *Graph 中注册页面。
  4. AppNavHost 中按模块组装 Graph。

步骤一:定义路由

路由统一放在 app/src/main/java/com/joker/kit/core/navigation/<module>/,并实现 NavKey

kotlin
object DemoRoutes {
    @Serializable
    data object NetworkDemo : NavKey

    @Serializable
    data class NavigationWithArgs(
        val goodsId: Long,
    ) : NavKey
}

说明:

  • 无参页面使用 data object
  • 带参页面使用 data class
  • 参数字段要语义化,避免使用不清晰命名。

步骤二:封装模块 Navigator(推荐)

在同模块新增 *Navigator.kt,统一对外暴露跳转方法:

kotlin
object DemoNavigator {
    fun toNetworkDemo() {
        navigate(DemoRoutes.NetworkDemo)
    }

    fun toNavigationWithArgs(goodsId: Long = 0) {
        navigate(DemoRoutes.NavigationWithArgs(goodsId = goodsId))
    }
}

这样业务层无需感知路由细节,也不会在多个页面重复写同样的跳转代码。

步骤三:注册模块 Graph

各 Feature 模块在 feature/<module>/navigation 提供 *Graph.kt

kotlin
fun EntryProviderScope<NavKey>.demoGraph() {
    entry<DemoRoutes.NetworkDemo> {
        NetworkDemoRoute()
    }
    entry<DemoRoutes.NavigationWithArgs> { key ->
        NavigationWithArgsRoute(navKey = key)
    }
}

说明:

  • 使用 entry<Route>() 进行类型安全注册。
  • 带参路由可以在 entry lambda 中直接拿到 key
  • Route 层负责把参数传给 ViewModel,不建议直接在 UI 层处理业务参数。

步骤四:在 AppNavHost 统一组装

AppNavHost.kt 中通过 entryProvider 聚合模块 Graph:

kotlin
private fun appEntryProvider() = entryProvider {
    mainGraph()
    demoGraph()
    authGraph()
    userGraph()
}

新增业务模块时,只需要新增自己的 *Routes*Navigator*Graph,再在这里挂一行即可。

参数传递到 ViewModel 的推荐写法

对于带参页面,建议在 Route 层把参数传入 ViewModel:

kotlin
@Composable
internal fun NavigationWithArgsRoute(
    navKey: DemoRoutes.NavigationWithArgs,
    viewModel: NavigationWithArgsViewModel = hiltViewModel<
        NavigationWithArgsViewModel,
        NavigationWithArgsViewModel.Factory
    >(creationCallback = { factory -> factory.create(navKey) })
) {
    NavigationWithArgsScreen(goodsId = viewModel.goodsId)
}

这种方式可以保证“参数用于请求数据”的场景在 ViewModel 层完成,UI 只负责展示状态。

扩展示例(新增 Goods 模块)

  1. core/navigation/goods/GoodsRoutes.kt 定义路由。
  2. core/navigation/goods/GoodsNavigator.kt 封装跳转方法。
  3. feature/goods/navigation/GoodsGraph.kt 注册 entry<GoodsRoutes.*>
  4. AppNavHost.appEntryProvider() 增加 goodsGraph()

小结

路由层保持三个原则:

  • 路由声明集中(*Routes)。
  • 跳转入口集中(*Navigator + 简写函数)。
  • 页面注册集中(*Graph)。

这样在多模块场景下,结构清晰、边界明确、可维护性更高。