21

我有两个片段。SecondFragmentThirdFragment。实际上,我使用导航组件在片段之间传递值。像这样:

第二片段

val action = SecondFragmentDirections.action_secondFragment_to_thirdFragment().setValue(1)

Navigation.findNavController(it).navigate(action)

这是我从ThirdFragment读取值的方式:

 arguments?.let {
           val args = ThirdFragmentArgs.fromBundle(it)
           thirdTextView.text = args.value.toString()
       }

它工作正常。现在我的堆栈是这样的:

ThirdFragment

SecondFragment 

使用新的导航组件将值从打开的ThirdFragment传递到前一个SecondFragment有任何选项吗?(当 ThirdFragment 完成时)

我知道 onActivityResult,但如果 Nav.Component 提供的解决方案比我想要的更好。

谢谢!

4

4 回答 4

18

这个答案有点晚了,但有人可能会觉得它有用。在导航组件库的更新版本中,现在可以在导航返回时传递数据。

假设堆栈是这样的

片段A --> 片段B。

我们现在在FragmentB,我们想在返回时传递数据FragmentA

在里面FragmentA我们可以创建一个带有键的观察者:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController()
// Instead of String any types of data can be used
navController.currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")
    ?.observe(viewLifecycleOwner) { 

    }
}

然后在内部FragmentB,如果我们通过访问先前的返回堆栈条目来更改它的值,它将被传播到FragmentA并通知观察者。

val navController = findNavController()
navController.previousBackStackEntry?.savedStateHandle?.set("key", "value that needs to be passed")
navController.popBackStack()
于 2020-09-13T14:14:58.587 回答
4

刚接触setFragmentResult(),很好用。这方面的文档在这里

如果您正在导航:片段 A -> 片段 B -> 片段 A 将其添加到片段 A:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setFragmentResultListener("requestKey") { requestKey, bundle ->
        shouldUpdate = bundle.getBoolean("bundleKey")
    }
}

然后在片段 B 中添加这行代码:

setFragmentResult("requestKey", bundleOf("bundleKey" to "value to pass back"))
// navigate back toFragment A

当您导航回片段 A 时,侦听器将触发,您将能够获取捆绑包中的数据。

于 2021-07-14T23:09:24.970 回答
0

您要求的是反模式。你应该要么

  • 使用您要设置的新值再次导航到第二个片段

  • 在单独的活动中使用第三个片段并以startActivityForResult()

  • 使用 ViewModel 或某种单例模式来保留您的数据(确保在不再需要数据后清除数据)

这些是我想到的一些模式。希望能帮助到你。

于 2018-10-04T20:54:39.277 回答
-1

如此处所述

使用操作进行导航时,您可以选择从后台堆栈中弹出其他目的地。例如,如果您的应用程序具有初始登录流程,则一旦用户登录,您应该将所有与登录相关的目的地从后台堆栈中弹出,以便“后退”按钮不会将用户带回登录流程。

要在从一个目的地导航到另一个目的地时弹出目的地,请将 app:popUpTo 属性添加到关联元素。app:popUpTo 告诉 Navigation 库从 back stack 中弹出一些目的地,作为调用 navigate() 的一部分。属性值是应保留在堆栈中的最新目的地的 ID。

<fragment
    android:id="@+id/c"
    android:name="com.example.myapplication.C"
    android:label="fragment_c"
    tools:layout="@layout/fragment_c">

    <action
        android:id="@+id/action_c_to_a"
        app:destination="@id/a"
        app:popUpTo="@+id/a"
        app:popUpToInclusive="true"/>
</fragment>
于 2020-04-27T15:38:52.673 回答