带有参数的导航组件.popBackStack()

时间:2018-07-13 13:36:38

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

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

SecondFragment

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 个答案:

答案 0 :(得分:2)

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

假设堆栈是这样的

FragmentA-> FragmentB。

我们目前位于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()

答案 1 :(得分:1)

您要的是反模式。您应该

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

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

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

这些是我想到的一些模式。希望对您有所帮助。

答案 2 :(得分:1)

described here

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

要在从一个目的地导航到另一个目的地时弹出目的地,请将app:popUpTo属性添加到关联的元素。 app:popUpTo告诉导航库将某些目标从后台堆栈弹出,作为对navigation()的调用的一部分。该属性值是应保留在堆栈中的最新目的地的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>

答案 3 :(得分:1)

刚遇到setFragmentResult(),非常好用。这方面的文档是 here

如果您正在导航:片段 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 时,侦听器将触发,您将能够获取包中的数据。