[英]how to pass a value back to previous fragment destination using Android navigation component?
let sat I have some destinations like this让坐吧 我有一些这样的目的地
from fragment A --> to fragment B --> to fragment C从片段 A --> 到片段 B --> 到片段 C
I can use Safe Args to pass data from fragment A to fragment B. and also using safe args from fragment B to fragment C.我可以使用 Safe Args 将数据从片段 A 传递到片段 B,也可以使用从片段 B 到片段 C 的安全参数。
what if I want to bring a string that generated in fragment C back to fragment B or to fragment A ?如果我想将片段 C 中生成的字符串带回片段 B 或片段 A 怎么办?
to navigate from fragment C to fragment B, I use code:要从片段 C 导航到片段 B,我使用代码:
Navigation.findNavController(fragmentView).navigateUp()
and to navigate from fragment C to fragment A, I use code:并从片段 C 导航到片段 A,我使用代码:
Navigation.findNavController(view).popBackStack(R.id.fragmentA, false)
so how to pass a value back to previous fragment destination ?那么如何将值传递回之前的片段目的地? do I have to make an action back from fragment C to fragment B and pass the value through safe args ?我是否必须从片段 C 返回到片段 B 并通过安全参数传递值?
really need your help.真的需要你的帮助。 Thank you very much :)非常感谢 :)
You can use the below snippet for sending data to previous fragment.您可以使用以下代码段将数据发送到前一个片段。
Fragment A observing the data:观察数据的片段A:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe(viewLifecycleOwner) { data ->
// Do something with the data.
}
}
Fragment B sending the data:发送数据的片段B:
findNavController().previousBackStackEntry?.savedStateHandle?.set("key", data)
findNavController().popBackStack()
I also wrote extensions for this.我还为此编写了扩展程序。
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)
}
}
Usage:用法:
Fragment A:片段A:
getBackStackData<String>("key") { data ->
// Do something with the data.
}
Fragment B:片段B:
setBackStackData("key",data)
Note: I am using String as data.注意:我使用 String 作为数据。 You may use any other type of variable.您可以使用任何其他类型的变量。
Note: If you are going to use a Class as data, don't forget to add @Parcelize
annotation and extend Parcelable
.注意:如果你要使用一个类的数据,不要忘记添加@Parcelize
注释和扩展Parcelable
。
You can create two buttons in every fragment, one to move to the next fragment (FragmentA to FragmentB) and others to move back (FragmentB to FragmentA). 您可以在每个片段中创建两个按钮,一个按钮移至下一个片段(FragmentA至FragmentB),其他按钮向后移(FragmentB至FragmentA)。 Then you'll be able to pass data from A to B and B to A back using safe args in the button onClick() method like 然后,您可以使用按钮onClick()方法中的安全参数将数据从A传递到B并将B传递回A
@Override
public void onClick(View view) {
int amount = 20;
ConfirmationAction action = SpecifyAmountFragmentDirections.confirmationAction();
action.setAmount(amount);
Navigation.findNavController(view).navigate(action);
}
i have just came across the same problem and have several options i can propose (currently considering myself which ones is best for my use case).我刚刚遇到了同样的问题,并且有几个我可以提出的选项(目前正在考虑哪些最适合我的用例)。
popUpTo
and PopUpToInclusive
.为避免这种情况,您可以使用popUpTo
和PopUpToInclusive
。 see the documentation .请参阅文档。the disadvantage of this method is that fragment A will be cleared no matter what, and would have to re-load (and fetch all its' data again).这种方法的缺点是无论如何都会清除片段 A,并且必须重新加载(并再次获取其所有数据)。
use a shared ViewModel
between for your fragments, and observe the required value with LiveData
.在片段之间使用共享的ViewModel
,并使用LiveData
观察所需的值。 in this scenario, fragment C will update a LiveData
value in the shared ViewModel
, which fragment A observes.在这种情况下,片段 C 将更新共享ViewModel
的LiveData
值,片段 A 观察到该值。 now when you go back to fragment A, your observer
will be triggered with the value set by fragment C.现在当你回到片段 A 时,你的observer
将被片段 C 设置的值触发。
similar to option 2, if you are using an external data source (like a Room
database) you can observe changes using LiveData
in fragment A. all fragment C has to do in this case is update the data source, and fragment A will automatically be updated through the LiveData
与选项 2 类似,如果您使用外部数据源(如Room
数据库),您可以使用片段 A 中的LiveData
观察更改。在这种情况下,片段 C 要做的就是更新数据源,片段 A 将自动更新通过LiveData
更新
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.