【问题标题】:how to pass a value back to previous fragment destination using Android navigation component?如何使用 Android 导航组件将值传递回先前的片段目标?
【发布时间】:2019-08-18 01:40:24
【问题描述】:

坐下来,我有一些这样的目的地

从片段 A --> 到片段 B --> 到片段 C

我可以使用安全参数将数据从片段 A 传递到片段 B。也可以使用安全参数从片段 B 到片段 C。

如果我想将片段 C 中生成的字符串带回片段 B 或片段 A 怎么办?

要从片段 C 导航到片段 B,我使用代码:

Navigation.findNavController(fragmentView).navigateUp()

为了从片段 C 导航到片段 A,我使用代码:

Navigation.findNavController(view).popBackStack(R.id.fragmentA, false)

那么如何将值传递回之前的片段目标?我是否必须从片段 C 回到片段 B 并通过安全参数传递值?

真的需要你的帮助。非常感谢:)

【问题讨论】:

  • 你试过使用接口吗?
  • @VivekSingh 使用接口创建一些监听器?
  • 如果您从 C 到 A 执行操作,则 B 仍将在您的后堆栈中,与 C 相同。
  • @ghita 那我该怎么办?你有过这个问题吗?
  • 我使用了带有 SharedPrefs 的 popBackStack。如果我能找到更好的解决方案,我会在这里发布。如果您找到更好的解决方案,请这样做,谢谢。

标签: android android-fragments android-jetpack android-navigation android-architecture-navigation


【解决方案1】:

您可以使用下面的 sn-p 将数据发送到上一个片段。

Fragment A 观察数据:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe(viewLifecycleOwner) { data ->
        // Do something with the data.
    }
}

Fragment B 发送数据:

findNavController().previousBackStackEntry?.savedStateHandle?.set("key", data)
findNavController().popBackStack()

我还为此编写了扩展。

fun <T : Any> Fragment.setBackStackData(key: String,data : T, doBack : Boolean = true) {
    findNavController().previousBackStackEntry?.savedStateHandle?.set(key, data)
    if(doBack)
    findNavController().popBackStack()
}

fun <T : Any> Fragment.getBackStackData(key: String, result: (T) -> (Unit)) {
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)?.observe(viewLifecycleOwner) {
        result(it)
    }
}

用法:

片段 A:

getBackStackData<String>("key") { data ->
    // Do something with the data.
}

片段 B:

setBackStackData("key",data)

    

注意:我使用字符串作为数据。您可以使用任何其他类型的变量。

注意:如果要使用 Class 作为数据,不要忘记添加 @Parcelize 注释并扩展 Parcelable

【讨论】:

  • 完美,如果有结果立即替换.getLiveData&lt;String&gt;("key")?.observe(viewLifecycleOwner) { data -&gt; on .get&lt;String&gt;("data")
【解决方案2】:

我刚刚遇到了同样的问题,并且有几个我可以提出的选项(目前我正在考虑哪些选项最适合我的用例)。

  1. 创建从片段 C 回到片段 A 的导航操作。请注意,如果这就是您所做的一切,那么您的堆栈现在将是:A-B-C-A。为避免这种情况,您可以使用popUpToPopUpToInclusive。见documentation

这种方法的缺点是片段 A 无论如何都会被清除,并且必须重新加载(并再次获取其所有数据)。

  1. 为您的片段使用共享的ViewModel,并使用LiveData 观察所需的值。在这种情况下,片段 C 将更新片段 A 观察到的共享 ViewModel 中的 LiveData 值。现在当你回到片段 A 时,你的 observer 将被片段 C 设置的值触发。

  2. 类似于选项 2,如果您使用外部数据源(如 Room 数据库),您可以使用片段 A 中的LiveData 观察更改。在这种情况下,所有片段 C 必须做的就是更新数据源,并且片段A会通过LiveData自动更新

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 2019-05-12
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多