我有两个片段。 SecondFragment
和ThirdFragment
。实际上,我使用导航组件在片段之间传递值。像这样:
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提供的解决方案比我想使用的更好。
谢谢!
答案 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)
使用操作进行导航时,可以选择将其他目标弹出后退栈。例如,如果您的应用程序具有初始登录流程,则在用户登录后,您应将所有与登录相关的目标从后退堆栈中弹出,以便“后退”按钮不会将用户带回到登录流程中。
要在从一个目的地导航到另一个目的地时弹出目的地,请将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 时,侦听器将触发,您将能够获取包中的数据。