Jetpack Compose 导航以获取结果

Elf*_*ama 4 android android-jetpack android-jetpack-navigation android-jetpack-compose

我在 Compose 版本中使用 Jetpack Navigation 库。我正在设置导航,就像这里显示的那样

我希望能够从屏幕 A 导航到屏幕 B。一旦 B 执行某些操作并从返回堆栈中弹出,它将返回屏幕 A 可以访问的结果。

我在这里找到了一种使用活动来做到这一点的方法,但我想避免创建任何额外的活动并在撰写中执行此操作。

Evg*_*kov 11

如果您只需要一次获取值,则需要在使用后删除值:

val screenResultState = navController.currentBackStackEntry
    ?.savedStateHandle
    ?.getLiveData<String>("some_key")?.observeAsState()

screenResultState?.value?.let {
    ...
    // make something, for example `viewModel.onResult(it)`
    ...
    //removing used value
    navController.currentBackStackEntry
        ?.savedStateHandle
        ?.remove<String>("some_key")
}
Run Code Online (Sandbox Code Playgroud)

我还在函数中提取它(对于 JetPack Compose)

@Composable
fun <T> NavController.GetOnceResult(keyResult: String, onResult: (T) -> Unit){
    val valueScreenResult =  currentBackStackEntry
        ?.savedStateHandle
        ?.getLiveData<T>(keyResult)?.observeAsState()

    valueScreenResult?.value?.let {
        onResult(it)
       
        currentBackStackEntry
            ?.savedStateHandle
            ?.remove<T>(keyResult)
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以将其复制到您的项目中并像这样使用:

navController.GetOnceResult<String>("some_key"){
    ...
    // make something
}
Run Code Online (Sandbox Code Playgroud)

  • `?.remove&lt;Long&gt;` 应该是 `?.remove&lt;T&gt;` (2认同)

ngl*_*ber 6

从要返回数据的 Composable 中,您可以执行以下操作:

navController.previousBackStackEntry
    ?.savedStateHandle
    ?.set("your_key", "your_value")
navController.popBackStack()
Run Code Online (Sandbox Code Playgroud)

然后,从源 Composable,您可以使用LiveData.

val secondScreenResult = navController.currentBackStackEntry
    ?.savedStateHandle
    ?.getLiveData<String>("your_key")?.observeAsState()
...
secondScreenResult?.value?.let {
    // Read the result
}
Run Code Online (Sandbox Code Playgroud)

  • 消费时不要忘记拔掉钥匙。 (5认同)
  • 您必须将 `implementation "androidx.compose.runtime:runtime-livedata:$compose_version"` 添加到 gradle 才能使 `observeAsState()` 正常工作(将 `$compose_version` 替换为实际版本)。 (4认同)
  • 有没有办法使用 ViewModel 中的 SavedStateHandle 来执行此操作,而不是在可组合项中侦听? (2认同)
  • 如果你需要从C返回一些数据到A,你应该从C返回到B,然后从B返回到A。但是如果你在调用C时弹出B,那么A将是C的前一个backstack,所以它应该工作。 (2认同)