Android Compose 的导航(Navigation)

基础知识

基本内容看官方吧: Android 使用 Compose 进行导航

B 回调数据给 A 内容

当您从 A 导航到 B 并且希望 B 将信息传回 A 时,您可以传递回调(此处onSelect):
有两者方法:自定义回调函数 and 使用相同ViewModel , 需要根据具体的应用场景和需求来选择适合的方法。

  • 如果仅需要简单的信息传递,回调函数可能是更直接和简单的选择。
  • 如果涉及到复杂的数据共享和状态管理,使用 ViewModel 可能更为合适和方便。

具体优缺点如下:
使用回调函数
优点:

  • 直接而简单:回调函数是一种直接的方式来传递信息,不需要引入额外的框架或组件。
  • 灵活性:可以通过定义不同的回调函数类型来传递不同类型的信息,适应不同的需求。
  • 易于理解和维护:回调函数的逻辑相对简单,易于理解和维护。

缺点:

  • 嵌套和管理:当存在多层回调时,可能需要嵌套回调函数,导致代码变得复杂。同时,需要仔细管理回调函数的生命周期和引用,以避免潜在的内存泄漏问题。

使用 ViewModel
优点:

  • 单一数据源:通过在共享的 ViewModel 中定义状态,可以实现页面间的数据共享和一致性。
  • 状态管理:ViewModel 提供了更好的状态管理机制,包括可观察的状态和状态更新的通知机制。
  • 生命周期感知:ViewModel 可以感知页面的生命周期,并确保数据在页面重建时正确保存和恢复。

缺点:

  • 引入依赖:使用 ViewModel 需要引入额外的依赖,例如 Jetpack Compose 中的 viewModel() 函数。
  • 需要关注作用域:需要注意 ViewModel 的作用域,以确保正确的共享和管理。

使用回调函数

在页面 A 中定义一个回调函数,并将其作为参数传递给页面 B。页面 B 可以调用该回调函数并传递信息回到页面 A。

建议阅读(封装案例)

建议阅读(不封装案例)

建议阅读(stackoverflow讨论)

下面为GPT生成:
在页面 A 中:

// 定义回调函数类型
typealias OnInfoReturned = (info: String) -> Unit

// 导航到页面 B 并传递回调函数
val navigateToPageB: (OnInfoReturned) -> Unit = { onInfoReturned ->
    navController.navigate("pageB") {
        // 传递回调函数
        launchSingleTop = true
        popUpTo(navController.graph.startDestinationId) {
            inclusive = false
        }
        // 传递回调函数作为参数
        putSerializable("onInfoReturned", onInfoReturned as Serializable)
    }
}

在页面 B 中:

// 获取回调函数参数
val onInfoReturned = remember {
    // 从导航参数中获取回调函数
    arguments?.getSerializable("onInfoReturned") as? OnInfoReturned
}

// 在适当的时机调用回调函数
onInfoReturned?.invoke("返回的信息")

使用 ViewModel

在页面 A 和页面 B 中共享一个共享的 ViewModel,并在 ViewModel 中定义可观察的状态以传递信息。

Google官方教程

下面为GPT生成:
在共享的 ViewModel 中:


class SharedViewModel : ViewModel() {
    private val _info = MutableStateFlow<String?>(null)
    val info: StateFlow<String?> = _info

    fun setInfo(info: String) {
        _info.value = info
    }
}

在页面 A 中:

val sharedViewModel: SharedViewModel = viewModel()

val navigateToPageB: () -> Unit = {
    navController.navigate("pageB") {
        launchSingleTop = true
    }
}

// 观察 ViewModel 中的状态
val info by sharedViewModel.info.collectAsState()

// 处理信息返回
LaunchedEffect(info) {
    info?.let { returnedInfo ->
        // 处理返回的信息
    }
}

在页面 B 中:

val sharedViewModel: SharedViewModel = viewModel()

// 设置信息并返回页面 A
sharedViewModel.setInfo("返回的信息")
navController.popBackStack()
posted @ 2023-11-28 10:56  kingwzun  阅读(324)  评论(0编辑  收藏  举报