返回

Compose Destinations 中 ViewModel 导航:告别可组合函数中的复杂性

Android

从 ViewModel 简化 Compose Destinations 导航

在开发 Compose Destinations 驱动的应用程序时,我们在可组合函数中处理导航可能会带来代码复杂度和可维护性挑战。通过将导航控制器注入一个单独的 Navigator 类,再将其注入 ViewModel,我们可以在 ViewModel 中直接进行导航,从而避免了在可组合函数中处理导航的问题。

步骤 1:创建 Navigator 类

Navigator 类充当导航控制器的封装,包含触发导航所需的方法。对于每个导航目标,创建一个相应的导航方法。例如,要导航到个人资料屏幕,可以定义一个名为 navigateToProfile 的方法。

步骤 2:在 ViewModel 中注入 Navigator

使用依赖注入库(如 Hilt)将 Navigator 注入到 ViewModel 中。这允许 ViewModel 直接访问导航控制器,而无需在可组合函数中处理它。

步骤 3:在可组合函数中使用 ViewModel

在可组合函数中,使用 ViewModel 来触发导航。当某些事件触发时(例如按钮点击),可以使用事件流通知 ViewModel,然后 ViewModel 调用适当的导航方法。这将有效地从可组合函数中分离出导航逻辑。

示例

让我们考虑一个示例,其中我们需要从欢迎屏幕导航到个人资料屏幕。

Navigator 类

class Navigator {

    fun navigateToProfile(param: Any) {
        // 触发导航到 Profile 屏幕,传递 param 作为参数
    }
}

WelcomeViewModel

class WelcomeViewModel @Inject constructor(
    private val navigator: Navigator
) : ViewModel() {

    fun onSomeAction() {
        // 进行一些计算
        navigator.navigateToProfile(param)
    }
}

Welcome 可组合函数

@Composable
fun Welcome(viewModel: WelcomeViewModel) {
    LaunchedEffect(key1 = true) {
        viewModel.eventFlow.collect { event ->
            when (event) {
                is WelcomeViewModel.Event.NavigateToProfile -> {
                    viewModel.onSomeAction() // 触发导航
                }
            }
        }
    }
    WelcomeView()
}

结论

通过将导航控制器分离到 Navigator 类,并将其注入 ViewModel,我们可以有效地简化导航逻辑,提高可组合函数的可维护性。这使我们能够专注于业务逻辑,同时保持代码的组织性。

常见问题解答

1. 为什么不直接在可组合函数中处理导航?

在可组合函数中处理导航会增加代码复杂度和难以维护,因为导航逻辑混杂在 UI 代码中。

2. 为什么使用 Navigator 类而不是直接使用 NavigationController?

Navigator 类作为一个轻量级包装器,可以隐藏 NavigationController 的复杂性,使导航更易于管理。

3. 这种方法是否适用于所有 Compose Destinations 导航场景?

是的,这种方法适用于大多数 Compose Destinations 导航场景,包括参数传递和有条件导航。

4. 如何处理嵌套导航?

对于嵌套导航,可以在 ViewModel 中使用多个 Navigator 实例,每个实例代表一个导航层次结构级别。

5. 这是否会影响应用程序的性能?

将导航逻辑分离到 ViewModel 中通常不会对性能产生显着影响,因为事件流和导航方法都是轻量级的操作。